├── Book3_Ch00_正文前__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch01_Python_Codes
├── Bk3_Ch01_01.ipynb
├── Bk3_Ch01_02.ipynb
├── Bk3_Ch01_03.ipynb
├── Bk3_Ch01_04.ipynb
├── Bk3_Ch01_05.ipynb
├── Bk3_Ch01_06.ipynb
├── Bk3_Ch01_07.ipynb
├── Bk3_Ch01_08.ipynb
├── Bk3_Ch01_09.ipynb
├── Bk3_Ch01_10.ipynb
├── Bk3_Ch01_11.ipynb
├── Bk3_Ch01_12.ipynb
└── Streamlit_Bk3_Ch01_02.py
├── Book3_Ch01_万物皆数__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch02_Python_Codes
├── Bk3_Ch02_01.ipynb
├── Bk3_Ch02_02.ipynb
├── Bk3_Ch02_03.ipynb
├── Bk3_Ch02_04.ipynb
├── Bk3_Ch02_05.ipynb
├── Bk3_Ch02_06.ipynb
├── Bk3_Ch02_07.ipynb
├── Bk3_Ch02_08.ipynb
├── Bk3_Ch02_09.ipynb
├── Bk3_Ch02_10.ipynb
├── Bk3_Ch02_11.ipynb
└── Streamlit_Bk3_Ch02_10.py
├── Book3_Ch02_乘除__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch03_Python_Codes
├── Bk3_Ch03_01.ipynb
├── Bk3_Ch03_02.ipynb
├── Bk3_Ch03_03.ipynb
├── Bk3_Ch03_04.ipynb
└── Streamlit_Bk3_Ch03_03.py
├── Book3_Ch03_几何__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch04_Python_Codes
├── Bk3_Ch04_01.ipynb
├── Bk3_Ch04_02.ipynb
├── Bk3_Ch04_03.ipynb
├── Bk3_Ch04_04.ipynb
├── Bk3_Ch04_05.ipynb
├── Bk3_Ch04_06.ipynb
├── Bk3_Ch04_07.ipynb
├── Bk3_Ch04_08.ipynb
├── Bk3_Ch04_09.ipynb
└── Streamlit_Bk3_Ch04_05.py
├── Book3_Ch04_代数__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch05_Python_Codes
├── Bk3_Ch05_01.ipynb
├── Bk3_Ch05_02.ipynb
├── Bk3_Ch05_03.ipynb
├── Bk3_Ch05_04.ipynb
├── Bk3_Ch05_05.ipynb
├── Bk3_Ch05_06.ipynb
└── Streamlit_Bk3_Ch05_03.py
├── Book3_Ch05_笛卡尔坐标系__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch06_Python_Codes
├── Bk3_Ch06_01.ipynb
├── Bk3_Ch06_02.ipynb
├── Bk3_Ch06_03.ipynb
├── Bk3_Ch06_04.ipynb
├── Bk3_Ch06_05.ipynb
├── Bk3_Ch06_06.ipynb
└── Streamlit_Bk3_Ch6_01.py
├── Book3_Ch06_三维坐标系__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch07_Python_Codes
├── Bk3_Ch07_01.ipynb
├── Bk3_Ch07_02.ipynb
├── Bk3_Ch07_03.ipynb
├── Bk3_Ch07_04.ipynb
├── Bk3_Ch07_05.ipynb
├── Bk3_Ch07_06.ipynb
└── Streamlit_Bk3_Ch07_06.py
├── Book3_Ch07_距离__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch08_Python_Codes
└── Bk3_Ch08_01.ipynb
├── Book3_Ch08_圆锥曲线__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch09_Python_Codes
├── Bk3_Ch09_01.ipynb
├── Bk3_Ch09_02.ipynb
├── Bk3_Ch09_03.ipynb
├── Bk3_Ch09_04.ipynb
├── Bk3_Ch09_05.ipynb
├── Streamlit_Bk3_Ch09_03.py
└── Streamlit_Bk3_Ch09_04.py
├── Book3_Ch09_深入圆锥曲线__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch10_Python_Codes
├── Bk3_Ch10_01.ipynb
├── Bk3_Ch10_02.ipynb
└── Streamlit_Bk3_Ch10_02.py
├── Book3_Ch10_函数__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch11_Python_Codes
├── Bk3_Ch11_01.ipynb
├── Bk3_Ch11_02.ipynb
├── Bk3_Ch11_03.ipynb
└── Streamlit_Bk3_Ch11_03.py
├── Book3_Ch11_代数函数__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch12_Python_Codes
├── Bk3_Ch12_01.ipynb
├── Bk3_Ch12_02.ipynb
└── Streamlit_Bk3_Ch12_02.py
├── Book3_Ch12_超越函数__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch13_Python_Codes
├── Bk3_Ch13_01.ipynb
├── Bk3_Ch13_02.ipynb
└── Streamlit_Bk3_Ch13_01.py
├── Book3_Ch13_二元函数__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch14_Python_Codes
├── Bk3_Ch14_01.ipynb
├── Bk3_Ch14_02.ipynb
├── Bk3_Ch14_03.ipynb
├── Bk3_Ch14_04.ipynb
├── Bk3_Ch14_05.ipynb
├── Bk3_Ch14_06.ipynb
└── Streamlit_Bk3_Ch14_02.py
├── Book3_Ch14_数列__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch15_Python_Codes
├── Bk3_Ch15_01.ipynb
├── Bk3_Ch15_02.ipynb
├── Bk3_Ch15_03.ipynb
├── Bk3_Ch15_04.ipynb
└── Streamlit_Bk3_Ch15_03.py
├── Book3_Ch15_导数__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch16_Python_Codes
├── Bk3_Ch16_01.ipynb
└── Streamlit_Bk3_Ch16_01.py
├── Book3_Ch16_偏导数__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch17_Python_Codes
├── Bk3_Ch17_01.ipynb
├── Bk3_Ch17_02.ipynb
├── Bk3_Ch17_03.ipynb
├── Bk3_Ch17_04.ipynb
├── Bk3_Ch17_05.ipynb
├── Bk3_Ch17_06.ipynb
├── Bk3_Ch17_07.ipynb
├── Streamlit_Bk3_Ch17_01.py
└── Streamlit_Bk3_Ch17_02.py
├── Book3_Ch17_微分__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch18_Python_Codes
├── Bk3_Ch18_01.ipynb
├── Bk3_Ch18_02.ipynb
├── Bk3_Ch18_03.ipynb
├── Bk3_Ch18_04.ipynb
├── Bk3_Ch18_05.ipynb
├── Bk3_Ch18_06.ipynb
├── Bk3_Ch18_07.ipynb
├── Bk3_Ch18_08.ipynb
└── Streamlit_Bk3_Ch18_07.py
├── Book3_Ch18_积分__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch19_Python_Codes
├── Bk3_Ch19_01.ipynb
├── Bk3_Ch19_02.ipynb
├── Bk3_Ch19_03.ipynb
├── Bk3_Ch19_04.ipynb
├── Bk3_Ch19_05.ipynb
├── Bk3_Ch19_06.ipynb
├── Bk3_Ch19_07.ipynb
└── Bk3_Ch19_08.ipynb
├── Book3_Ch19_优化入门__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch20_Python_Codes
├── Bk3_Ch20_01.ipynb
├── Bk3_Ch20_02.ipynb
├── Streamlit_Bk3_Ch20_01.py
└── Streamlit_Bk3_Ch20_02.py
├── Book3_Ch20_概率入门__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch21_Python_Codes
├── Bk3_Ch21_01.ipynb
└── Streamlit_Bk3_Ch21_01.py
├── Book3_Ch21_统计入门__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch22_Python_Codes
├── Bk3_Ch22_01.ipynb
├── Bk3_Ch22_02.ipynb
├── Bk3_Ch22_03.ipynb
└── Bk3_Ch22_04.ipynb
├── Book3_Ch22_向量__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch23_Python_Codes
├── Bk3_Ch23_01.ipynb
├── Bk3_Ch23_02.ipynb
├── Bk3_Ch23_03.ipynb
├── Bk3_Ch23_04.ipynb
└── Streamlit_Bk3_Ch23_02.py
├── Book3_Ch23_鸡兔同笼1__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch24_Python_Codes
├── Bk3_Ch24_01.ipynb
├── Bk3_Ch24_02.ipynb
├── Bk3_Ch24_03.ipynb
├── Bk3_Ch24_04.ipynb
└── Streamlit_Bk3_Ch24_02.py
├── Book3_Ch24_鸡兔同笼2__数学要素__从加减乘除到机器学习.pdf
├── Book3_Ch25_Python_Codes
├── Bk3_Ch25_01.ipynb
├── Bk3_Ch25_02.ipynb
├── Bk3_Ch25_03.ipynb
├── Streamlit_Bk3_Ch25_02.py
└── Streamlit_Bk3_Ch25_03.py
├── Book3_Ch25_鸡兔同笼3__数学要素__从加减乘除到机器学习.pdf
├── README.md
└── 鸢尾花书_整体布局.pdf
/Book3_Ch00_正文前__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch00_正文前__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch01_Python_Codes/Bk3_Ch01_01.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 01\n",
9 | "\n",
10 | "# 无理数\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "080d7f5f-1279-44de-b938-3606bf8662ab",
17 | "metadata": {},
18 | "source": [
19 | "该代码主要使用Python的`math`库来输出一些常见的数学常数:圆周率$\\pi$、自然对数的底数$e$,以及数值$2$的平方根$\\sqrt{2}$。\n",
20 | "\n",
21 | "首先,代码导入`math`库,这是Python内置的一个数学模块,提供了多种数学常量和函数。接着,代码依次输出了以下三个常数的数值:\n",
22 | "\n",
23 | "1. **圆周率$\\pi$**:圆周率$\\pi$的值定义为一个圆的周长与直径的比值,其数值大约为$3.14159$。在代码中,`math.pi`用于访问此常量。\n",
24 | "\n",
25 | " $$\n",
26 | " \\pi \\approx 3.14159\n",
27 | " $$\n",
28 | "\n",
29 | "2. **自然常数$e$**:$e$是自然对数的底数,大约为$2.71828$,在数学和物理学中常用于描述指数增长和衰减过程。代码中的`math.e`返回此常量。\n",
30 | "\n",
31 | " $$\n",
32 | " e \\approx 2.71828\n",
33 | " $$\n",
34 | "\n",
35 | "3. **平方根$\\sqrt{2}$**:这是一个无理数,表示数值$2$的平方根。平方根的定义是一个数乘以自身等于$2$,即$\\sqrt{2} \\times \\sqrt{2} = 2$,其近似值为$1.41421$。代码中的`math.sqrt(2)`计算并返回该值。\n",
36 | "\n",
37 | " $$\n",
38 | " \\sqrt{2} \\approx 1.41421\n",
39 | " $$\n",
40 | "\n",
41 | "总结而言,该代码通过`math`库提供的接口直接输出$\\pi$、$e$和$\\sqrt{2}$的数值,展示了Python如何使用数学常数和基本函数。"
42 | ]
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "id": "bfa721f3-0190-46be-9cd7-c427ec877ed2",
47 | "metadata": {},
48 | "source": [
49 | "## 导入数学库"
50 | ]
51 | },
52 | {
53 | "cell_type": "code",
54 | "execution_count": 1,
55 | "id": "bf7a52bb-eacc-4448-94e2-a8110878c277",
56 | "metadata": {},
57 | "outputs": [],
58 | "source": [
59 | "import math # 导入math库"
60 | ]
61 | },
62 | {
63 | "cell_type": "markdown",
64 | "id": "4b7670bf-e909-487b-9f1a-2f15acabfd81",
65 | "metadata": {},
66 | "source": [
67 | "## 打印数学常量"
68 | ]
69 | },
70 | {
71 | "cell_type": "code",
72 | "execution_count": 2,
73 | "id": "8ca981a5-3712-40a2-a306-ed653115a0b1",
74 | "metadata": {},
75 | "outputs": [
76 | {
77 | "name": "stdout",
78 | "output_type": "stream",
79 | "text": [
80 | "pi = 3.141592653589793\n"
81 | ]
82 | }
83 | ],
84 | "source": [
85 | "print('pi = ', math.pi) # 输出π的值"
86 | ]
87 | },
88 | {
89 | "cell_type": "code",
90 | "execution_count": 3,
91 | "id": "9a45dc7f-6b95-48b8-98d2-0fcda1b8a59c",
92 | "metadata": {},
93 | "outputs": [
94 | {
95 | "name": "stdout",
96 | "output_type": "stream",
97 | "text": [
98 | "e = 2.718281828459045\n"
99 | ]
100 | }
101 | ],
102 | "source": [
103 | "print('e = ', math.e) # 输出自然常数e的值"
104 | ]
105 | },
106 | {
107 | "cell_type": "code",
108 | "execution_count": 4,
109 | "id": "cf32cf91-9028-4c75-bf16-cab134c3cd95",
110 | "metadata": {},
111 | "outputs": [
112 | {
113 | "name": "stdout",
114 | "output_type": "stream",
115 | "text": [
116 | "sqrt(2) = 1.4142135623730951\n"
117 | ]
118 | }
119 | ],
120 | "source": [
121 | "print('sqrt(2) = ', math.sqrt(2)) # 输出2的平方根"
122 | ]
123 | },
124 | {
125 | "cell_type": "code",
126 | "execution_count": null,
127 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
128 | "metadata": {},
129 | "outputs": [],
130 | "source": []
131 | },
132 | {
133 | "cell_type": "code",
134 | "execution_count": null,
135 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
136 | "metadata": {},
137 | "outputs": [],
138 | "source": []
139 | }
140 | ],
141 | "metadata": {
142 | "kernelspec": {
143 | "display_name": "Python 3 (ipykernel)",
144 | "language": "python",
145 | "name": "python3"
146 | },
147 | "language_info": {
148 | "codemirror_mode": {
149 | "name": "ipython",
150 | "version": 3
151 | },
152 | "file_extension": ".py",
153 | "mimetype": "text/x-python",
154 | "name": "python",
155 | "nbconvert_exporter": "python",
156 | "pygments_lexer": "ipython3",
157 | "version": "3.12.7"
158 | }
159 | },
160 | "nbformat": 4,
161 | "nbformat_minor": 5
162 | }
163 |
--------------------------------------------------------------------------------
/Book3_Ch01_Python_Codes/Bk3_Ch01_03.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 01\n",
9 | "\n",
10 | "# 奇偶数\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "0bf9b79b-3c16-4d38-b20a-3ed18c43f494",
17 | "metadata": {},
18 | "source": [
19 | "该代码通过用户输入一个数字来判断该数字的类型,具体来说,是判断它是否为整数以及是否为偶数或奇数。 \n",
20 | "\n",
21 | "### 代码细节\n",
22 | "\n",
23 | "1. **用户输入**:代码首先让用户输入一个数字,并将其转换为浮点数。这种转换使得即便用户输入的是小数,也能正常处理。\n",
24 | "\n",
25 | "2. **整数判断**:代码使用`num.is_integer()`方法来检测该数字是否为整数。对于一个浮点数$x$,如果$x$是整数,则其满足$x = n$,其中$n$是整数。如果$x$包含小数部分,即$x = n + r$,其中$r \\neq 0$,则它被视为非整数。\n",
26 | "\n",
27 | "3. **偶数或奇数判断**:当输入的数字是整数时,代码进一步检查其是否为偶数或奇数。偶数定义为能够被$2$整除的数,即满足以下条件的数:\n",
28 | "\n",
29 | " $$\n",
30 | " x \\mod 2 = 0\n",
31 | " $$\n",
32 | "\n",
33 | " 如果该条件成立,则输出数字是偶数;否则,该整数为奇数:\n",
34 | "\n",
35 | " $$\n",
36 | " x \\mod 2 = 1\n",
37 | " $$\n",
38 | "\n",
39 | "4. **非整数处理**:如果输入的数字不是整数(即带有小数部分),代码直接输出该数字不是整数的信息。\n",
40 | "\n",
41 | "### 总结\n",
42 | "\n",
43 | "总体而言,代码通过判断用户输入的数字是否是整数以及它是否能被$2$整除来识别数字的类型。该逻辑确保无论用户输入何种数值,代码都能判断它是偶数、奇数还是非整数,给出相应的提示。"
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "id": "6d3f36b4-3508-4e5c-9aad-9db8848df11a",
49 | "metadata": {},
50 | "source": [
51 | "## 判断一个数是否为偶数或奇数"
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": 1,
57 | "id": "a53bb21c-dee0-4be4-9e66-7acbc4772f8a",
58 | "metadata": {},
59 | "outputs": [
60 | {
61 | "name": "stdin",
62 | "output_type": "stream",
63 | "text": [
64 | "Enter a number: 6\n"
65 | ]
66 | }
67 | ],
68 | "source": [
69 | "num = float(input(\"Enter a number: \")) # 输入一个数字并转换为浮点数"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "id": "5b9a07ce-82fd-4157-83e3-d346d8530fe3",
75 | "metadata": {},
76 | "source": [
77 | "## 检查输入的数字是否为整数"
78 | ]
79 | },
80 | {
81 | "cell_type": "code",
82 | "execution_count": 2,
83 | "id": "f5daa794-1cc9-4336-b18b-57ff3c34fbe3",
84 | "metadata": {},
85 | "outputs": [
86 | {
87 | "name": "stdout",
88 | "output_type": "stream",
89 | "text": [
90 | "6 is even \n"
91 | ]
92 | }
93 | ],
94 | "source": [
95 | "if num.is_integer(): # 如果数字为整数\n",
96 | "\n",
97 | " ## 判断整数是偶数还是奇数\n",
98 | " if (num % 2) == 0: # 如果数字除以2的余数为0,则为偶数\n",
99 | " print(\"{0} is even \".format(int(num))) # 输出偶数信息\n",
100 | " else: # 否则为奇数\n",
101 | " print(\"{0} is odd \".format(int(num))) # 输出奇数信息\n",
102 | "\n",
103 | "else: # 如果数字不是整数\n",
104 | " print(\"{0} is not an integer \".format(num)) # 输出非整数信息"
105 | ]
106 | },
107 | {
108 | "cell_type": "code",
109 | "execution_count": null,
110 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
111 | "metadata": {},
112 | "outputs": [],
113 | "source": []
114 | },
115 | {
116 | "cell_type": "code",
117 | "execution_count": null,
118 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
119 | "metadata": {},
120 | "outputs": [],
121 | "source": []
122 | }
123 | ],
124 | "metadata": {
125 | "kernelspec": {
126 | "display_name": "Python 3 (ipykernel)",
127 | "language": "python",
128 | "name": "python3"
129 | },
130 | "language_info": {
131 | "codemirror_mode": {
132 | "name": "ipython",
133 | "version": 3
134 | },
135 | "file_extension": ".py",
136 | "mimetype": "text/x-python",
137 | "name": "python",
138 | "nbconvert_exporter": "python",
139 | "pygments_lexer": "ipython3",
140 | "version": "3.12.7"
141 | }
142 | },
143 | "nbformat": 4,
144 | "nbformat_minor": 5
145 | }
146 |
--------------------------------------------------------------------------------
/Book3_Ch01_Python_Codes/Bk3_Ch01_04.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 01\n",
9 | "\n",
10 | "# 加法\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "eff70c40-3e99-47f4-a51c-6a8b69b62957",
17 | "metadata": {},
18 | "source": [
19 | "该代码定义了两个数字$2$和$3$,然后计算并显示它们的和。\n",
20 | "\n",
21 | "### 代码细节\n",
22 | "\n",
23 | "1. **定义数字**:代码将两个数分别赋值给变量`num1`和`num2`,其中$ \\text{num1} = 2 $,$ \\text{num2} = 3 $。\n",
24 | "\n",
25 | "2. **求和计算**:代码计算两个数的和,并将结果存储在`sum_2_nums`变量中。具体的计算过程如下:\n",
26 | "\n",
27 | " $$\n",
28 | " \\text{sum\\_2\\_nums} = \\text{num1} + \\text{num2} = 2 + 3 = 5\n",
29 | " $$\n",
30 | "\n",
31 | "3. **结果显示**:代码通过格式化字符串输出计算结果,将变量`num1`、`num2`及其和`sum_2_nums`的值插入到输出字符串中,最终显示为“`The sum of 2 and 3 is 5`”。\n",
32 | "\n",
33 | "### 总结\n",
34 | "\n",
35 | "该代码通过简单的加法运算展示了如何使用Python的格式化输出功能来显示计算结果,强调了数值运算与输出的结合。"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "id": "0449cc37-eb6a-4b4b-b681-1de28396a1e5",
41 | "metadata": {},
42 | "source": [
43 | "## 定义两个数字并计算其和"
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": 1,
49 | "id": "90667c8e-a5ef-4a7d-b41d-2bde55ed2cf7",
50 | "metadata": {},
51 | "outputs": [],
52 | "source": [
53 | "num1 = 2 # 定义第一个数字\n",
54 | "num2 = 3 # 定义第二个数字"
55 | ]
56 | },
57 | {
58 | "cell_type": "markdown",
59 | "id": "ba5fc825-980d-47b3-9e02-957969b7af9b",
60 | "metadata": {},
61 | "source": [
62 | "## 计算两个数字的和"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": 2,
68 | "id": "590df95d-7126-40da-8c45-2a4e4639bdbe",
69 | "metadata": {},
70 | "outputs": [],
71 | "source": [
72 | "sum_2_nums = num1 + num2 # 计算num1和num2的和"
73 | ]
74 | },
75 | {
76 | "cell_type": "markdown",
77 | "id": "f23d32df-b7c1-4732-b80d-1a0d5c0a61ff",
78 | "metadata": {},
79 | "source": [
80 | "## 显示计算结果"
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": 3,
86 | "id": "bb7061b2-8268-4222-876c-7a7a867a6a84",
87 | "metadata": {},
88 | "outputs": [
89 | {
90 | "name": "stdout",
91 | "output_type": "stream",
92 | "text": [
93 | "The sum of 2 and 3 is 5\n"
94 | ]
95 | }
96 | ],
97 | "source": [
98 | "print('The sum of {0} and {1} is {2}'.format(num1, num2, sum_2_nums)) # 输出两个数字的和"
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": null,
104 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
105 | "metadata": {},
106 | "outputs": [],
107 | "source": []
108 | },
109 | {
110 | "cell_type": "code",
111 | "execution_count": null,
112 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
113 | "metadata": {},
114 | "outputs": [],
115 | "source": []
116 | }
117 | ],
118 | "metadata": {
119 | "kernelspec": {
120 | "display_name": "Python 3 (ipykernel)",
121 | "language": "python",
122 | "name": "python3"
123 | },
124 | "language_info": {
125 | "codemirror_mode": {
126 | "name": "ipython",
127 | "version": 3
128 | },
129 | "file_extension": ".py",
130 | "mimetype": "text/x-python",
131 | "name": "python",
132 | "nbconvert_exporter": "python",
133 | "pygments_lexer": "ipython3",
134 | "version": "3.12.7"
135 | }
136 | },
137 | "nbformat": 4,
138 | "nbformat_minor": 5
139 | }
140 |
--------------------------------------------------------------------------------
/Book3_Ch01_Python_Codes/Bk3_Ch01_05.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 01\n",
9 | "\n",
10 | "# 加法\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "fd2510b4-eaf7-47a0-a42a-dfe9168b828d",
17 | "metadata": {},
18 | "source": [
19 | "该代码通过用户输入两个数字,将它们相加并输出结果。它使用Python的`input`函数获取用户输入的数字,并进行类型转换、加法运算和格式化输出。\n",
20 | "\n",
21 | "### 代码细节\n",
22 | "\n",
23 | "1. **用户输入**:程序首先提示用户输入两个数字,存储为变量`num1`和`num2`。输入值默认以字符串形式保存。\n",
24 | "\n",
25 | "2. **类型转换与求和**:代码使用`float()`函数将字符串形式的输入值转换为浮点数,以便进行加法运算。假设用户输入的两个数分别为$x$和$y$,加法计算如下:\n",
26 | "\n",
27 | " $$\n",
28 | " \\text{sum\\_2\\_nums} = x + y\n",
29 | " $$\n",
30 | "\n",
31 | "3. **结果显示**:代码通过格式化字符串将输入的两个数字及其和插入到输出字符串中。假设用户输入的数字为$x = 2.5$和$y = 3.7$,则输出结果为:\n",
32 | "\n",
33 | " $$\n",
34 | " \\text{The sum of 2.5 and 3.7 is 6.2}\n",
35 | " $$\n",
36 | "\n",
37 | "### 总结\n",
38 | "\n",
39 | "此代码展示了如何将用户输入的字符串转换为浮点数,并通过加法运算获取和。它使用格式化输出方式将计算结果和输入值一起呈现出来,适用于动态地获取用户输入、处理数值计算并输出结果的情境。"
40 | ]
41 | },
42 | {
43 | "cell_type": "markdown",
44 | "id": "ad368ff4-5ad2-4309-957c-49b7f8325101",
45 | "metadata": {},
46 | "source": [
47 | "## 用户输入两个数字并计算其和"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": 1,
53 | "id": "36503fa8-6c5c-44c9-bca8-0ad9ef5a7f92",
54 | "metadata": {},
55 | "outputs": [
56 | {
57 | "name": "stdin",
58 | "output_type": "stream",
59 | "text": [
60 | "Enter first number: 2.5\n"
61 | ]
62 | }
63 | ],
64 | "source": [
65 | "num1 = input('Enter first number: ') # 输入第一个数字"
66 | ]
67 | },
68 | {
69 | "cell_type": "code",
70 | "execution_count": 2,
71 | "id": "625e4637-7311-4bde-a9b7-f787e37719c5",
72 | "metadata": {},
73 | "outputs": [
74 | {
75 | "name": "stdin",
76 | "output_type": "stream",
77 | "text": [
78 | "Enter second number: 3.7\n"
79 | ]
80 | }
81 | ],
82 | "source": [
83 | "num2 = input('Enter second number: ') # 输入第二个数字"
84 | ]
85 | },
86 | {
87 | "cell_type": "markdown",
88 | "id": "f6c2f1b6-d516-4bab-b55e-4d0963da3716",
89 | "metadata": {},
90 | "source": [
91 | "## 计算两个数字的和"
92 | ]
93 | },
94 | {
95 | "cell_type": "code",
96 | "execution_count": 3,
97 | "id": "a3d41ffb-2f69-4e40-8f1c-da86d2d9f1e4",
98 | "metadata": {},
99 | "outputs": [],
100 | "source": [
101 | "sum_2_nums = float(num1) + float(num2) # 将输入的数字转换为浮点数后求和"
102 | ]
103 | },
104 | {
105 | "cell_type": "markdown",
106 | "id": "2b207d98-88db-4495-9d1e-3672469a85c8",
107 | "metadata": {},
108 | "source": [
109 | "## 显示计算结果"
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": 4,
115 | "id": "57418cae-3cb8-4b6a-898a-b0149564bd05",
116 | "metadata": {},
117 | "outputs": [
118 | {
119 | "name": "stdout",
120 | "output_type": "stream",
121 | "text": [
122 | "The sum of 2.5 and 3.7 is 6.2\n"
123 | ]
124 | }
125 | ],
126 | "source": [
127 | "print('The sum of {0} and {1} is {2}'.format(num1, num2, sum_2_nums)) # 输出两个数字的和"
128 | ]
129 | },
130 | {
131 | "cell_type": "code",
132 | "execution_count": null,
133 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
134 | "metadata": {},
135 | "outputs": [],
136 | "source": []
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": null,
141 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
142 | "metadata": {},
143 | "outputs": [],
144 | "source": []
145 | }
146 | ],
147 | "metadata": {
148 | "kernelspec": {
149 | "display_name": "Python 3 (ipykernel)",
150 | "language": "python",
151 | "name": "python3"
152 | },
153 | "language_info": {
154 | "codemirror_mode": {
155 | "name": "ipython",
156 | "version": 3
157 | },
158 | "file_extension": ".py",
159 | "mimetype": "text/x-python",
160 | "name": "python",
161 | "nbconvert_exporter": "python",
162 | "pygments_lexer": "ipython3",
163 | "version": "3.12.7"
164 | }
165 | },
166 | "nbformat": 4,
167 | "nbformat_minor": 5
168 | }
169 |
--------------------------------------------------------------------------------
/Book3_Ch01_Python_Codes/Bk3_Ch01_06.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 01\n",
9 | "\n",
10 | "# 累计求和\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "036f8706-7898-4d78-8adf-8d6d20586330",
17 | "metadata": {},
18 | "source": [
19 | "该代码利用`numpy`库生成一个从$1$到$10$的等间距数组,并计算该数组的累积和。这种计算方式在数值分析和数据处理过程中很常见,尤其是在累积求和等累加操作中。\n",
20 | "\n",
21 | "### 代码细节\n",
22 | "\n",
23 | "1. **生成等间距数组**:代码首先使用`np.linspace(1, 10, 10)`生成一个包含10个元素的数组,其中起点为$1$,终点为$10$,每个元素之间间隔相等。生成的数组为:\n",
24 | "\n",
25 | " $$\n",
26 | " a_i = [1.0, 2.0, 3.0, \\dots, 10.0]\n",
27 | " $$\n",
28 | "\n",
29 | "2. **计算累积和**:累积和是指逐步对数组的元素进行相加操作。在此代码中,`np.cumsum(a_i)`将计算数组`a_i`的累积和,形成一个新数组`a_i\\_cumsum`,其中每个元素表示从起始元素到当前元素的总和。累积和的计算公式为:\n",
30 | "\n",
31 | " $$\n",
32 | " a_i\\_cumsum[n] = \\sum_{k=1}^{n} a_i[k]\n",
33 | " $$\n",
34 | "\n",
35 | " 结果为:\n",
36 | "\n",
37 | " $$\n",
38 | " a_i\\_cumsum = [1.0, 3.0, 6.0, 10.0, \\dots, 55.0]\n",
39 | " $$\n",
40 | "\n",
41 | " 例如,$a_i\\_cumsum[3] = a_i[1] + a_i[2] + a_i[3] = 1 + 2 + 3 = 6$。\n",
42 | "\n",
43 | "### 总结\n",
44 | "\n",
45 | "代码通过生成等间距数组并计算其累积和,展示了如何逐步累加数据。这一操作在时间序列数据、累计分布计算和递增数据分析中非常有用。"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "id": "f840061d-c8cd-4bda-8ee7-eb5be80e6a7e",
51 | "metadata": {},
52 | "source": [
53 | "## 生成等间距数组并计算其累积和"
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": 1,
59 | "id": "85980af0-9d2b-4098-8113-a4746bb88910",
60 | "metadata": {},
61 | "outputs": [],
62 | "source": [
63 | "import numpy as np # 导入numpy库"
64 | ]
65 | },
66 | {
67 | "cell_type": "markdown",
68 | "id": "5f1afebc-a83a-4a93-931b-3a9f01a86766",
69 | "metadata": {},
70 | "source": [
71 | "## 生成一个从1到10的等间距数组"
72 | ]
73 | },
74 | {
75 | "cell_type": "code",
76 | "execution_count": 2,
77 | "id": "c0051b82-77b7-4800-985f-87ef38f90dc1",
78 | "metadata": {},
79 | "outputs": [
80 | {
81 | "name": "stdout",
82 | "output_type": "stream",
83 | "text": [
84 | "[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]\n"
85 | ]
86 | }
87 | ],
88 | "source": [
89 | "a_i = np.linspace(1, 10, 10) # 创建包含10个数的等间距数组\n",
90 | "print(a_i) # 输出数组a_i"
91 | ]
92 | },
93 | {
94 | "cell_type": "markdown",
95 | "id": "d1b23bc4-fa1d-4071-a59a-3d839e4cd971",
96 | "metadata": {},
97 | "source": [
98 | "## 计算数组的累积和"
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": 3,
104 | "id": "1d6ed3aa-efb5-4971-9c00-2ddd9fb268b1",
105 | "metadata": {},
106 | "outputs": [
107 | {
108 | "name": "stdout",
109 | "output_type": "stream",
110 | "text": [
111 | "[ 1. 3. 6. 10. 15. 21. 28. 36. 45. 55.]\n"
112 | ]
113 | }
114 | ],
115 | "source": [
116 | "a_i_cumsum = np.cumsum(a_i) # 计算a_i的累积和\n",
117 | "print(a_i_cumsum) # 输出累积和结果"
118 | ]
119 | },
120 | {
121 | "cell_type": "code",
122 | "execution_count": null,
123 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
124 | "metadata": {},
125 | "outputs": [],
126 | "source": []
127 | },
128 | {
129 | "cell_type": "code",
130 | "execution_count": null,
131 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
132 | "metadata": {},
133 | "outputs": [],
134 | "source": []
135 | }
136 | ],
137 | "metadata": {
138 | "kernelspec": {
139 | "display_name": "Python 3 (ipykernel)",
140 | "language": "python",
141 | "name": "python3"
142 | },
143 | "language_info": {
144 | "codemirror_mode": {
145 | "name": "ipython",
146 | "version": 3
147 | },
148 | "file_extension": ".py",
149 | "mimetype": "text/x-python",
150 | "name": "python",
151 | "nbconvert_exporter": "python",
152 | "pygments_lexer": "ipython3",
153 | "version": "3.12.7"
154 | }
155 | },
156 | "nbformat": 4,
157 | "nbformat_minor": 5
158 | }
159 |
--------------------------------------------------------------------------------
/Book3_Ch01_Python_Codes/Bk3_Ch01_07.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 01\n",
9 | "\n",
10 | "# 减法\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "23e2bb33-4777-45cc-90ad-fb20f2f1ce9a",
17 | "metadata": {},
18 | "source": [
19 | "该代码计算并输出两个数字之间的差值。首先,它定义了两个数字$5$和$3$,分别赋值给变量`num1`和`num2`,然后通过减法运算求出它们的差。 \n",
20 | "\n",
21 | "### 代码细节\n",
22 | "\n",
23 | "1. **计算差值**:代码通过减法计算`num1`和`num2`的差值,并将结果存储在变量`diff`中。计算公式为:\n",
24 | "\n",
25 | " $$\n",
26 | " \\text{diff} = \\text{num1} - \\text{num2}\n",
27 | " $$\n",
28 | "\n",
29 | " 代入数值后,结果为:\n",
30 | "\n",
31 | " $$\n",
32 | " \\text{diff} = 5 - 3 = 2\n",
33 | " $$\n",
34 | "\n",
35 | "2. **结果显示**:代码使用格式化字符串将计算结果输出到屏幕上,显示为“`The difference of 5 and 3 is 2`”。\n",
36 | "\n",
37 | "### 总结\n",
38 | "\n",
39 | "该代码简单地演示了如何进行基本的减法运算以及如何通过格式化输出结果。它展示了通过变量存储计算结果并使用格式化字符串将计算细节输出的过程。"
40 | ]
41 | },
42 | {
43 | "cell_type": "markdown",
44 | "id": "ff843b05-e211-4e3d-ba1c-445430d2d618",
45 | "metadata": {},
46 | "source": [
47 | "## 计算两个数字的差值并显示结果"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": 1,
53 | "id": "dd24d931-2562-4cb4-b398-2fb520d704b0",
54 | "metadata": {},
55 | "outputs": [],
56 | "source": [
57 | "num1 = 5 # 定义第一个数字\n",
58 | "num2 = 3 # 定义第二个数字"
59 | ]
60 | },
61 | {
62 | "cell_type": "markdown",
63 | "id": "40f507f3-c38e-485d-9841-95c270e82715",
64 | "metadata": {},
65 | "source": [
66 | "## 计算两个数字的差值"
67 | ]
68 | },
69 | {
70 | "cell_type": "code",
71 | "execution_count": 2,
72 | "id": "9447c235-e3b3-4d79-8a11-d49e6082b977",
73 | "metadata": {},
74 | "outputs": [],
75 | "source": [
76 | "diff = num1 - num2 # 计算num1和num2的差值"
77 | ]
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "id": "c4888afa-5b77-49b9-8c68-512ef1679d1e",
82 | "metadata": {},
83 | "source": [
84 | "## 显示计算结果"
85 | ]
86 | },
87 | {
88 | "cell_type": "code",
89 | "execution_count": 3,
90 | "id": "575aa4fc-4dd2-44a3-bbda-4c3d21adce51",
91 | "metadata": {},
92 | "outputs": [
93 | {
94 | "name": "stdout",
95 | "output_type": "stream",
96 | "text": [
97 | "The difference of 5 and 3 is 2\n"
98 | ]
99 | }
100 | ],
101 | "source": [
102 | "print('The difference of {0} and {1} is {2}'.format(num1, num2, diff)) # 输出两个数字的差值"
103 | ]
104 | },
105 | {
106 | "cell_type": "code",
107 | "execution_count": null,
108 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
109 | "metadata": {},
110 | "outputs": [],
111 | "source": []
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": null,
116 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
117 | "metadata": {},
118 | "outputs": [],
119 | "source": []
120 | }
121 | ],
122 | "metadata": {
123 | "kernelspec": {
124 | "display_name": "Python 3 (ipykernel)",
125 | "language": "python",
126 | "name": "python3"
127 | },
128 | "language_info": {
129 | "codemirror_mode": {
130 | "name": "ipython",
131 | "version": 3
132 | },
133 | "file_extension": ".py",
134 | "mimetype": "text/x-python",
135 | "name": "python",
136 | "nbconvert_exporter": "python",
137 | "pygments_lexer": "ipython3",
138 | "version": "3.12.7"
139 | }
140 | },
141 | "nbformat": 4,
142 | "nbformat_minor": 5
143 | }
144 |
--------------------------------------------------------------------------------
/Book3_Ch01_Python_Codes/Bk3_Ch01_08.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 01\n",
9 | "\n",
10 | "# 行向量、列向量\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "31d85d2b-23f1-4ede-89a4-e1253b1c51bc",
17 | "metadata": {},
18 | "source": [
19 | "该代码使用`numpy`库在Python中创建和转置行向量与列向量,演示了向量在不同形态之间的转换过程。这种转换在线性代数中非常重要,特别是在矩阵运算和数据处理过程中。\n",
20 | "\n",
21 | "### 代码细节\n",
22 | "\n",
23 | "1. **行向量转置为列向量**:代码首先定义了一个行向量$a\\_\\text{row} = [1, 2, 3]$,并通过转置操作`a_row.T`将其转换为列向量$b$。转置后的列向量表示为:\n",
24 | "\n",
25 | " $$\n",
26 | " b = \\begin{bmatrix} 1 \\\\ 2 \\\\ 3 \\end{bmatrix}\n",
27 | " $$\n",
28 | "\n",
29 | " 这种转置操作将原来的单行多列矩阵转换为多行单列矩阵。\n",
30 | "\n",
31 | "2. **列向量转置为行向量**:代码接下来定义了一个列向量$b\\_\\text{col} = \\begin{bmatrix} 1 \\\\ 2 \\\\ 3 \\end{bmatrix}$,并通过转置操作`b_col.T`将其转换为行向量$a$。转置后的行向量表示为:\n",
32 | "\n",
33 | " $$\n",
34 | " a = \\begin{bmatrix} 1 & 2 & 3 \\end{bmatrix}\n",
35 | " $$\n",
36 | "\n",
37 | " 这种操作将原来的单列多行矩阵转换为多列单行矩阵。\n",
38 | "\n",
39 | "### 总结\n",
40 | "\n",
41 | "该代码展示了如何通过转置操作在行向量和列向量之间进行切换。行向量与列向量的转置本质上是对矩阵维度的调整,使得数据可以在不同的维度上操作和计算,这在矩阵乘法、线性变换和机器学习数据处理中尤为关键。"
42 | ]
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "id": "63c9154e-352b-4df9-a23a-469c79a7b9a3",
47 | "metadata": {},
48 | "source": [
49 | "## 转置行向量和列向量的操作"
50 | ]
51 | },
52 | {
53 | "cell_type": "code",
54 | "execution_count": 1,
55 | "id": "0bc2bf33-2005-41cd-8ea8-58dae9ab463b",
56 | "metadata": {},
57 | "outputs": [],
58 | "source": [
59 | "import numpy as np # 导入numpy库"
60 | ]
61 | },
62 | {
63 | "cell_type": "markdown",
64 | "id": "ad927e09-9187-48cd-b1a1-166fd0820dc0",
65 | "metadata": {},
66 | "source": [
67 | "## 定义一个行向量并转置为列向量"
68 | ]
69 | },
70 | {
71 | "cell_type": "code",
72 | "execution_count": 2,
73 | "id": "dc7139a2-dc2b-43ba-b718-1b65a2f8b41b",
74 | "metadata": {},
75 | "outputs": [
76 | {
77 | "data": {
78 | "text/plain": [
79 | "array([[1, 2, 3]])"
80 | ]
81 | },
82 | "execution_count": 2,
83 | "metadata": {},
84 | "output_type": "execute_result"
85 | }
86 | ],
87 | "source": [
88 | "a_row = np.array([[1, 2, 3]]) # 定义一个行向量\n",
89 | "a_row # 输出行向量"
90 | ]
91 | },
92 | {
93 | "cell_type": "code",
94 | "execution_count": 3,
95 | "id": "64a21eba-175f-4e4d-b56f-dc743812a5a5",
96 | "metadata": {},
97 | "outputs": [
98 | {
99 | "data": {
100 | "text/plain": [
101 | "array([[1],\n",
102 | " [2],\n",
103 | " [3]])"
104 | ]
105 | },
106 | "execution_count": 3,
107 | "metadata": {},
108 | "output_type": "execute_result"
109 | }
110 | ],
111 | "source": [
112 | "b = a_row.T # 将行向量转置为列向量\n",
113 | "b # 输出列向量"
114 | ]
115 | },
116 | {
117 | "cell_type": "markdown",
118 | "id": "0e79be6f-2149-4764-9dea-6c7de866e03c",
119 | "metadata": {},
120 | "source": [
121 | "## 定义一个列向量并转置为行向量"
122 | ]
123 | },
124 | {
125 | "cell_type": "code",
126 | "execution_count": 4,
127 | "id": "ee76779b-e513-40c3-8877-496d76217159",
128 | "metadata": {},
129 | "outputs": [
130 | {
131 | "data": {
132 | "text/plain": [
133 | "array([[1],\n",
134 | " [2],\n",
135 | " [3]])"
136 | ]
137 | },
138 | "execution_count": 4,
139 | "metadata": {},
140 | "output_type": "execute_result"
141 | }
142 | ],
143 | "source": [
144 | "b_col = np.array([[1], [2], [3]]) # 定义一个列向量\n",
145 | "b_col # 输出列向量"
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": 5,
151 | "id": "d7980f2b-f0de-4ac5-ad7e-fe604fbcb55d",
152 | "metadata": {},
153 | "outputs": [
154 | {
155 | "data": {
156 | "text/plain": [
157 | "array([[1, 2, 3]])"
158 | ]
159 | },
160 | "execution_count": 5,
161 | "metadata": {},
162 | "output_type": "execute_result"
163 | }
164 | ],
165 | "source": [
166 | "a = b_col.T # 将列向量转置为行向量\n",
167 | "a # 输出行向量"
168 | ]
169 | },
170 | {
171 | "cell_type": "code",
172 | "execution_count": null,
173 | "id": "db5c8cbf-2da5-4e2f-91fc-76c97986a261",
174 | "metadata": {},
175 | "outputs": [],
176 | "source": []
177 | }
178 | ],
179 | "metadata": {
180 | "kernelspec": {
181 | "display_name": "Python 3 (ipykernel)",
182 | "language": "python",
183 | "name": "python3"
184 | },
185 | "language_info": {
186 | "codemirror_mode": {
187 | "name": "ipython",
188 | "version": 3
189 | },
190 | "file_extension": ".py",
191 | "mimetype": "text/x-python",
192 | "name": "python",
193 | "nbconvert_exporter": "python",
194 | "pygments_lexer": "ipython3",
195 | "version": "3.12.7"
196 | }
197 | },
198 | "nbformat": 4,
199 | "nbformat_minor": 5
200 | }
201 |
--------------------------------------------------------------------------------
/Book3_Ch01_Python_Codes/Bk3_Ch01_10.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 01\n",
9 | "\n",
10 | "# 行向量相加\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "8057895f-67f3-4dc4-af93-015327de21e6",
17 | "metadata": {},
18 | "source": [
19 | "该代码展示了四种对两个列表中的元素进行逐项相加的方法,结果都是对列表`list1 = [1, 2, 3]`和`list2 = [4, 5, 6]`的逐元素相加操作。\n",
20 | "\n",
21 | "1. **列表推导式与`zip`函数**:使用`zip`函数将`list1`和`list2`中的元素配对,依次将每对元素相加,形成一个新的列表:\n",
22 | "\n",
23 | " $$\n",
24 | " [x + y \\text{ for } x, y \\text{ in zip(list1, list2)}] = [1 + 4, 2 + 5, 3 + 6] = [5, 7, 9]\n",
25 | " $$\n",
26 | "\n",
27 | "2. **`map`和`lambda`函数**:使用`map`函数与`lambda`表达式逐项相加,每对元素的计算结果与上述相同:\n",
28 | "\n",
29 | " $$\n",
30 | " \\text{map(lambda x, y: x + y, list1, list2)} = [5, 7, 9]\n",
31 | " $$\n",
32 | "\n",
33 | "3. **`numpy`数组直接相加**:将`list1`和`list2`转换为`numpy`数组,然后使用`x + y`进行逐项相加。`numpy`支持数组间的逐项运算,结果与前述相同:\n",
34 | "\n",
35 | " $$\n",
36 | " x + y = [5, 7, 9]\n",
37 | " $$\n",
38 | "\n",
39 | "4. **`numpy.add`函数**:使用`numpy`的`add`函数对`list1`和`list2`进行逐项相加。`np.add`是一种矢量化的相加操作,与直接相加相同,结果为:\n",
40 | "\n",
41 | " $$\n",
42 | " \\text{np.add(list1, list2)} = [5, 7, 9]\n",
43 | " $$\n",
44 | "\n",
45 | "\n",
46 | "\n",
47 | "这段代码展示了在Python中对列表元素逐项相加的不同方法,包括纯Python方法和`numpy`方法。使用`numpy`方法尤其适合大规模数据计算,因为`numpy`的运算经过优化,适合处理数组和矩阵等大数据。"
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "id": "60566858-8d51-4513-a4ab-91026ec4ca48",
53 | "metadata": {},
54 | "source": [
55 | "## 使用不同方法对两个列表元素进行逐项相加"
56 | ]
57 | },
58 | {
59 | "cell_type": "code",
60 | "execution_count": 1,
61 | "id": "97f3cbfe-87ef-4656-b171-2c1de3fde533",
62 | "metadata": {},
63 | "outputs": [],
64 | "source": [
65 | "list1 = [1, 2, 3] # 定义第一个列表\n",
66 | "list2 = [4, 5, 6] # 定义第二个列表"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "id": "5220c1da-0c78-4930-bc28-d66999d97b2d",
72 | "metadata": {},
73 | "source": [
74 | "## 使用列表推导式和zip函数逐项相加"
75 | ]
76 | },
77 | {
78 | "cell_type": "code",
79 | "execution_count": 2,
80 | "id": "aa4c6fb6-bf42-4ba4-92c6-d096cc11fc2c",
81 | "metadata": {},
82 | "outputs": [
83 | {
84 | "name": "stdout",
85 | "output_type": "stream",
86 | "text": [
87 | "[5, 7, 9]\n"
88 | ]
89 | }
90 | ],
91 | "source": [
92 | "print([x + y for x, y in zip(list1, list2)]) # 输出列表推导式计算结果"
93 | ]
94 | },
95 | {
96 | "cell_type": "markdown",
97 | "id": "7b192d8e-90d2-46ef-93db-54f99adf6a26",
98 | "metadata": {},
99 | "source": [
100 | "## 使用map和lambda函数逐项相加"
101 | ]
102 | },
103 | {
104 | "cell_type": "code",
105 | "execution_count": 3,
106 | "id": "f8d6640c-5592-4f80-b57b-daec7131e648",
107 | "metadata": {},
108 | "outputs": [
109 | {
110 | "name": "stdout",
111 | "output_type": "stream",
112 | "text": [
113 | "[5, 7, 9]\n"
114 | ]
115 | }
116 | ],
117 | "source": [
118 | "print(list(map(lambda x, y: x + y, list1, list2))) # 输出map和lambda函数计算结果"
119 | ]
120 | },
121 | {
122 | "cell_type": "markdown",
123 | "id": "ab5914f9-c6ee-45d1-9e2c-57703d29623c",
124 | "metadata": {},
125 | "source": [
126 | "## 使用numpy对两个数组逐项相加"
127 | ]
128 | },
129 | {
130 | "cell_type": "code",
131 | "execution_count": 4,
132 | "id": "7cf9d235-cd58-4a9d-bccb-8af021c79e28",
133 | "metadata": {},
134 | "outputs": [
135 | {
136 | "name": "stdout",
137 | "output_type": "stream",
138 | "text": [
139 | "[5 7 9]\n"
140 | ]
141 | }
142 | ],
143 | "source": [
144 | "import numpy as np # 导入numpy库\n",
145 | "\n",
146 | "x = np.array(list1) # 将list1转换为numpy数组x\n",
147 | "y = np.array(list2) # 将list2转换为numpy数组y\n",
148 | "print(x + y) # 使用numpy数组直接逐项相加并输出结果"
149 | ]
150 | },
151 | {
152 | "cell_type": "markdown",
153 | "id": "8da81a42-1cf4-4553-8d17-77f441cec920",
154 | "metadata": {},
155 | "source": [
156 | "## 使用numpy的add函数对两个列表逐项相加"
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": 5,
162 | "id": "99a034a9-2d2f-4f4a-b008-2c391cba2a13",
163 | "metadata": {},
164 | "outputs": [
165 | {
166 | "name": "stdout",
167 | "output_type": "stream",
168 | "text": [
169 | "[5 7 9]\n"
170 | ]
171 | }
172 | ],
173 | "source": [
174 | "print(np.add(list1, list2)) # 使用numpy的add函数进行相加并输出结果"
175 | ]
176 | },
177 | {
178 | "cell_type": "code",
179 | "execution_count": null,
180 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
181 | "metadata": {},
182 | "outputs": [],
183 | "source": []
184 | }
185 | ],
186 | "metadata": {
187 | "kernelspec": {
188 | "display_name": "Python 3 (ipykernel)",
189 | "language": "python",
190 | "name": "python3"
191 | },
192 | "language_info": {
193 | "codemirror_mode": {
194 | "name": "ipython",
195 | "version": 3
196 | },
197 | "file_extension": ".py",
198 | "mimetype": "text/x-python",
199 | "name": "python",
200 | "nbconvert_exporter": "python",
201 | "pygments_lexer": "ipython3",
202 | "version": "3.12.7"
203 | }
204 | },
205 | "nbformat": 4,
206 | "nbformat_minor": 5
207 | }
208 |
--------------------------------------------------------------------------------
/Book3_Ch01_Python_Codes/Bk3_Ch01_11.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 01\n",
9 | "\n",
10 | "# 矩阵加法\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "65712911-cb84-41fe-a87a-3b3705b4976f",
17 | "metadata": {},
18 | "source": [
19 | "该代码定义了两个矩阵$A$和$B$,并计算它们的逐元素和。矩阵逐元素相加的原理是对矩阵中的每个对应位置的元素执行加法运算。\n",
20 | "\n",
21 | "1. **定义矩阵**:矩阵$A$和$B$分别定义如下:\n",
22 | "\n",
23 | " $$\n",
24 | " A = \\begin{bmatrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\end{bmatrix}\n",
25 | " $$\n",
26 | "\n",
27 | " $$\n",
28 | " B = \\begin{bmatrix} 1 & 0 & 0 \\\\ 0 & 1 & 0 \\end{bmatrix}\n",
29 | " $$\n",
30 | "\n",
31 | "2. **逐元素相加**:代码通过双重列表推导式进行逐元素相加。对于矩阵中每个位置的元素$A[i][j]$和$B[i][j]$,计算它们的和并生成新矩阵`A_plus_B`:\n",
32 | "\n",
33 | " $$\n",
34 | " A\\_plus\\_B = \\begin{bmatrix} A[0][0] + B[0][0] & A[0][1] + B[0][1] & A[0][2] + B[0][2] \\\\ A[1][0] + B[1][0] & A[1][1] + B[1][1] & A[1][2] + B[1][2] \\end{bmatrix}\n",
35 | " $$\n",
36 | "\n",
37 | " 计算后的结果为:\n",
38 | "\n",
39 | " $$\n",
40 | " A\\_plus\\_B = \\begin{bmatrix} 2 & 2 & 3 \\\\ 4 & 6 & 6 \\end{bmatrix}\n",
41 | " $$\n",
42 | "\n"
43 | ]
44 | },
45 | {
46 | "cell_type": "markdown",
47 | "id": "94ecb0d9-5de2-4517-9a1f-74f34cdea28d",
48 | "metadata": {},
49 | "source": [
50 | "## 定义两个矩阵并计算其逐元素相加"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": 1,
56 | "id": "eba98b97-8d2e-4fc1-8456-1d51b279b9af",
57 | "metadata": {},
58 | "outputs": [
59 | {
60 | "data": {
61 | "text/plain": [
62 | "[[1, 2, 3], [4, 5, 6]]"
63 | ]
64 | },
65 | "execution_count": 1,
66 | "metadata": {},
67 | "output_type": "execute_result"
68 | }
69 | ],
70 | "source": [
71 | "A = [[1, 2, 3], # 定义矩阵A\n",
72 | " [4, 5, 6]]\n",
73 | "A # 输出矩阵A"
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": 2,
79 | "id": "a8af49f4-0133-4f00-a5c9-eb95abe107dd",
80 | "metadata": {},
81 | "outputs": [
82 | {
83 | "data": {
84 | "text/plain": [
85 | "[[1, 0, 0], [0, 1, 0]]"
86 | ]
87 | },
88 | "execution_count": 2,
89 | "metadata": {},
90 | "output_type": "execute_result"
91 | }
92 | ],
93 | "source": [
94 | "B = [[1, 0, 0], # 定义矩阵B\n",
95 | " [0, 1, 0]]\n",
96 | "B # 输出矩阵B"
97 | ]
98 | },
99 | {
100 | "cell_type": "markdown",
101 | "id": "b9c9eb31-9fa6-4dd4-ac61-46932ea0209a",
102 | "metadata": {},
103 | "source": [
104 | "## 逐元素相加矩阵A和矩阵B"
105 | ]
106 | },
107 | {
108 | "cell_type": "code",
109 | "execution_count": 3,
110 | "id": "fdbcfbcd-370d-45b0-968d-37149750e8f5",
111 | "metadata": {},
112 | "outputs": [],
113 | "source": [
114 | "A_plus_B = [[A[i][j] + B[i][j] # 计算矩阵A和B中对应元素的和\n",
115 | " for j in range(len(A[0]))] # 遍历矩阵列\n",
116 | " for i in range(len(A))] # 遍历矩阵行"
117 | ]
118 | },
119 | {
120 | "cell_type": "code",
121 | "execution_count": 4,
122 | "id": "ba49388a-3a8e-4fde-9f02-4ea8ad87187f",
123 | "metadata": {},
124 | "outputs": [
125 | {
126 | "name": "stdout",
127 | "output_type": "stream",
128 | "text": [
129 | "[[2, 2, 3], [4, 6, 6]]\n"
130 | ]
131 | }
132 | ],
133 | "source": [
134 | "print(A_plus_B) # 输出矩阵A和B逐元素相加的结果"
135 | ]
136 | },
137 | {
138 | "cell_type": "code",
139 | "execution_count": null,
140 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
141 | "metadata": {},
142 | "outputs": [],
143 | "source": []
144 | }
145 | ],
146 | "metadata": {
147 | "kernelspec": {
148 | "display_name": "Python 3 (ipykernel)",
149 | "language": "python",
150 | "name": "python3"
151 | },
152 | "language_info": {
153 | "codemirror_mode": {
154 | "name": "ipython",
155 | "version": 3
156 | },
157 | "file_extension": ".py",
158 | "mimetype": "text/x-python",
159 | "name": "python",
160 | "nbconvert_exporter": "python",
161 | "pygments_lexer": "ipython3",
162 | "version": "3.12.7"
163 | }
164 | },
165 | "nbformat": 4,
166 | "nbformat_minor": 5
167 | }
168 |
--------------------------------------------------------------------------------
/Book3_Ch01_Python_Codes/Bk3_Ch01_12.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 01\n",
9 | "\n",
10 | "# 矩阵加法,向量化运算\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "272ea6e0-6024-4f46-a4c6-7b4b678e0ca0",
17 | "metadata": {},
18 | "source": [
19 | "该代码使用`numpy`库对两个矩阵$A$和$B$进行逐元素相加,并展示了两种方法:直接转换为`numpy`数组相加和使用`numpy`的`add`函数。矩阵逐元素相加是指对于两个大小相同的矩阵,将它们的对应位置的元素分别相加,形成新的矩阵。\n",
20 | "\n",
21 | "### 代码细节\n",
22 | "\n",
23 | "1. **定义矩阵**:代码定义了两个矩阵$A$和$B$,矩阵$A$为:\n",
24 | "\n",
25 | " $$\n",
26 | " A = \\begin{bmatrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\end{bmatrix}\n",
27 | " $$\n",
28 | "\n",
29 | " 矩阵$B$为:\n",
30 | "\n",
31 | " $$\n",
32 | " B = \\begin{bmatrix} 1 & 0 & 0 \\\\ 0 & 1 & 0 \\end{bmatrix}\n",
33 | " $$\n",
34 | "\n",
35 | "2. **逐元素相加**:\n",
36 | " - 使用`np.array(A) + np.array(B)`:首先将$A$和$B$转换为`numpy`数组,再进行逐元素相加。结果为:\n",
37 | "\n",
38 | " $$\n",
39 | " A + B = \\begin{bmatrix} 2 & 2 & 3 \\\\ 4 & 6 & 6 \\end{bmatrix}\n",
40 | " $$\n",
41 | "\n",
42 | " - 使用`np.add(A, B)`:`numpy`的`add`函数用于逐元素相加,得到与前一种方法相同的结果。\n",
43 | "\n",
44 | "### 总结\n",
45 | "\n",
46 | "这段代码展示了在`numpy`中对矩阵进行逐元素相加的便捷性。对于矩阵$A$和$B$的对应位置上的每个元素$A[i][j]$和$B[i][j]$,计算它们的和,得到新的矩阵。这种逐元素相加方式在科学计算和数据处理中特别常见。"
47 | ]
48 | },
49 | {
50 | "cell_type": "markdown",
51 | "id": "26f3d8be-6fbf-4d58-a731-1a487f0ac796",
52 | "metadata": {},
53 | "source": [
54 | "## 使用numpy对两个矩阵进行逐元素相加"
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": 2,
60 | "id": "450fd65e-f818-4602-a5bd-f80100d34762",
61 | "metadata": {},
62 | "outputs": [],
63 | "source": [
64 | "import numpy as np # 导入numpy库"
65 | ]
66 | },
67 | {
68 | "cell_type": "code",
69 | "execution_count": 3,
70 | "id": "dcf1b9d4-7b0e-46de-a8ea-bf9e78882849",
71 | "metadata": {},
72 | "outputs": [],
73 | "source": [
74 | "A = [[1, 2, 3], # 定义矩阵A\n",
75 | " [4, 5, 6]]\n",
76 | "# A = np.array(A)"
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": 4,
82 | "id": "6010c989-cdcc-4549-857d-45e058454c34",
83 | "metadata": {},
84 | "outputs": [],
85 | "source": [
86 | "B = [[1, 0, 0], # 定义矩阵B\n",
87 | " [0, 1, 0]]\n",
88 | "# B = np.array(B)"
89 | ]
90 | },
91 | {
92 | "cell_type": "markdown",
93 | "id": "1ba46565-0b12-4f47-950c-d85ffaa2b436",
94 | "metadata": {},
95 | "source": [
96 | "## 使用numpy的数组相加方法对矩阵A和矩阵B逐元素相加"
97 | ]
98 | },
99 | {
100 | "cell_type": "code",
101 | "execution_count": 6,
102 | "id": "3ff797b0-4c01-45cb-974c-3323b1b9e5bc",
103 | "metadata": {},
104 | "outputs": [
105 | {
106 | "name": "stdout",
107 | "output_type": "stream",
108 | "text": [
109 | "[[2 2 3]\n",
110 | " [4 6 6]]\n"
111 | ]
112 | }
113 | ],
114 | "source": [
115 | "print(np.array(A) + np.array(B)) # 将A和B转换为numpy数组并逐元素相加"
116 | ]
117 | },
118 | {
119 | "cell_type": "markdown",
120 | "id": "e7392c67-6e4a-4bb4-9eea-5bbcf73a2f0b",
121 | "metadata": {},
122 | "source": [
123 | "## 使用numpy的add函数对矩阵A和矩阵B逐元素相加"
124 | ]
125 | },
126 | {
127 | "cell_type": "code",
128 | "execution_count": 8,
129 | "id": "12b2a460-1611-40bb-bd42-924c878838be",
130 | "metadata": {},
131 | "outputs": [
132 | {
133 | "name": "stdout",
134 | "output_type": "stream",
135 | "text": [
136 | "[[2 2 3]\n",
137 | " [4 6 6]]\n"
138 | ]
139 | }
140 | ],
141 | "source": [
142 | "print(np.add(A, B)) # 使用numpy的add函数逐元素相加并输出结果"
143 | ]
144 | },
145 | {
146 | "cell_type": "code",
147 | "execution_count": null,
148 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
149 | "metadata": {},
150 | "outputs": [],
151 | "source": []
152 | },
153 | {
154 | "cell_type": "code",
155 | "execution_count": null,
156 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
157 | "metadata": {},
158 | "outputs": [],
159 | "source": []
160 | }
161 | ],
162 | "metadata": {
163 | "kernelspec": {
164 | "display_name": "Python 3 (ipykernel)",
165 | "language": "python",
166 | "name": "python3"
167 | },
168 | "language_info": {
169 | "codemirror_mode": {
170 | "name": "ipython",
171 | "version": 3
172 | },
173 | "file_extension": ".py",
174 | "mimetype": "text/x-python",
175 | "name": "python",
176 | "nbconvert_exporter": "python",
177 | "pygments_lexer": "ipython3",
178 | "version": "3.12.7"
179 | }
180 | },
181 | "nbformat": 4,
182 | "nbformat_minor": 5
183 | }
184 |
--------------------------------------------------------------------------------
/Book3_Ch01_Python_Codes/Streamlit_Bk3_Ch01_02.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | # 导入必要的库
9 | from mpmath import mp # 用于高精度计算
10 | import streamlit as st # 用于创建交互式Web应用
11 | import numpy as np # 用于数值计算
12 | import matplotlib.pyplot as plt # 用于绘制图形
13 |
14 | # 添加Streamlit侧边栏用户输入
15 | with st.sidebar:
16 | # 用户选择小数位数
17 | num_digits = st.slider('Number of decimal digits:', # 滑块标题
18 | min_value=10000, # 最小值为10,000
19 | max_value=100000, # 最大值为100,000
20 | step=10000) # 每次增加的步长为10,000
21 |
22 | # 设置mpmath的计算精度为用户选择的位数加2(额外位数用于内部计算)
23 | mp.dps = num_digits + 2
24 |
25 | # 获取π的高精度小数部分
26 | pi_digits = mp.pi # 计算π的高精度值
27 | pi_digits = str(pi_digits)[2:] # 转换为字符串并去掉小数点前的部分
28 |
29 | # 将小数部分的每一位转换为整数列表
30 | pi_digits_list = [int(x) for x in pi_digits]
31 |
32 | # 将整数列表转换为NumPy数组
33 | pi_digits_array = np.array(pi_digits_list)
34 |
35 | # 统计每个数字(0-9)的出现次数
36 | counts = np.bincount(pi_digits_array)
37 |
38 | # 创建一个水平条形图来显示数字的出现次数
39 | fig, ax = plt.subplots() # 创建图形和子图
40 | ## 设置背景透明
41 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
42 | ax.set_facecolor('none') # 设置坐标轴背景为透明
43 | # 绘制水平条形图
44 | ax.barh(range(10), counts, align='center',
45 | edgecolor=[0.6, 0.6, 0.6]) # 灰色边框
46 |
47 | # 去掉顶部和右侧的坐标轴边框
48 | ax.spines['top'].set_visible(False)
49 | ax.spines['right'].set_visible(False)
50 |
51 | # 添加x轴和y轴标签
52 | ax.set_xlabel('Count') # x轴标签
53 | ax.set_ylabel('Digit, 0~9') # y轴标签
54 |
55 | # 设置y轴刻度标签为数字0到9
56 | plt.yticks(range(10))
57 |
58 | # 在Streamlit应用中显示绘制的图形
59 | st.pyplot(fig)
60 |
--------------------------------------------------------------------------------
/Book3_Ch01_万物皆数__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch01_万物皆数__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch02_Python_Codes/Bk3_Ch02_01.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 02\n",
9 | "\n",
10 | "# 乘法\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "57f8b381-c7ec-4a36-a46f-33245d8367be",
17 | "metadata": {},
18 | "source": [
19 | "该代码计算两个数字的乘积并输出结果。首先定义了两个数字$2$和$3$,分别赋值给变量`num1`和`num2`。然后通过乘法运算求出它们的乘积。\n",
20 | "\n",
21 | "### 代码细节\n",
22 | "\n",
23 | "1. **乘积计算**:代码通过`num1 * num2`计算乘积,将结果存储在变量`prod`中。乘积公式为:\n",
24 | "\n",
25 | " $$\n",
26 | " \\text{prod} = \\text{num1} \\times \\text{num2} = 2 \\times 3 = 6\n",
27 | " $$\n",
28 | "\n",
29 | "2. **结果显示**:代码使用格式化字符串将计算结果输出到屏幕,最终显示为“`The product of 2 and 3 is 6`”。\n",
30 | "\n",
31 | "### 总结\n",
32 | "\n",
33 | "这段代码展示了基本的乘法运算,将两个数字相乘并格式化输出。这种简单的乘积计算在数学运算和数值展示中广泛应用。"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "id": "59b86f9a-b73a-48b8-974a-ba5803676864",
39 | "metadata": {},
40 | "source": [
41 | "## 计算两个数字的乘积并显示结果"
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": 1,
47 | "id": "ae82d0c3-5670-413a-ad3a-9e80ae494d7c",
48 | "metadata": {},
49 | "outputs": [],
50 | "source": [
51 | "num1 = 2 # 定义第一个数字"
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": 2,
57 | "id": "ad1f4552-a706-47f7-ab80-f99cffdb2176",
58 | "metadata": {},
59 | "outputs": [],
60 | "source": [
61 | "num2 = 3 # 定义第二个数字"
62 | ]
63 | },
64 | {
65 | "cell_type": "markdown",
66 | "id": "fdc5db12-93fa-48fd-a91e-8544fdb5d155",
67 | "metadata": {},
68 | "source": [
69 | "## 计算两个数字的乘积"
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": 3,
75 | "id": "18c7fedf-3881-43ed-97d4-c881d70d4665",
76 | "metadata": {},
77 | "outputs": [],
78 | "source": [
79 | "prod = num1 * num2 # 计算num1和num2的乘积"
80 | ]
81 | },
82 | {
83 | "cell_type": "markdown",
84 | "id": "4fe3ac7f-34f6-4588-9d8b-d68abe35e257",
85 | "metadata": {},
86 | "source": [
87 | "## 显示计算结果"
88 | ]
89 | },
90 | {
91 | "cell_type": "code",
92 | "execution_count": 4,
93 | "id": "121bb6c5-683f-4eeb-9217-0fb893147c6c",
94 | "metadata": {},
95 | "outputs": [
96 | {
97 | "name": "stdout",
98 | "output_type": "stream",
99 | "text": [
100 | "The product of 2 and 3 is 6\n"
101 | ]
102 | }
103 | ],
104 | "source": [
105 | "print('The product of {0} and {1} is {2}'.format(num1, num2, prod)) # 输出两个数字的乘积"
106 | ]
107 | },
108 | {
109 | "cell_type": "code",
110 | "execution_count": null,
111 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
112 | "metadata": {},
113 | "outputs": [],
114 | "source": []
115 | },
116 | {
117 | "cell_type": "code",
118 | "execution_count": null,
119 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
120 | "metadata": {},
121 | "outputs": [],
122 | "source": []
123 | }
124 | ],
125 | "metadata": {
126 | "kernelspec": {
127 | "display_name": "Python 3 (ipykernel)",
128 | "language": "python",
129 | "name": "python3"
130 | },
131 | "language_info": {
132 | "codemirror_mode": {
133 | "name": "ipython",
134 | "version": 3
135 | },
136 | "file_extension": ".py",
137 | "mimetype": "text/x-python",
138 | "name": "python",
139 | "nbconvert_exporter": "python",
140 | "pygments_lexer": "ipython3",
141 | "version": "3.12.7"
142 | }
143 | },
144 | "nbformat": 4,
145 | "nbformat_minor": 5
146 | }
147 |
--------------------------------------------------------------------------------
/Book3_Ch02_Python_Codes/Bk3_Ch02_02.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 02\n",
9 | "\n",
10 | "# 阶乘\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "764c95c6-476c-4c40-bdf6-e458c704016f",
17 | "metadata": {},
18 | "source": [
19 | "该代码用于计算用户输入的整数的阶乘,适用于正整数和零的阶乘计算,并对负数输入进行处理。阶乘(Factorial)是指从$1$开始到该整数的所有正整数的乘积,记作$n!$。其定义如下:\n",
20 | "\n",
21 | "- 如果$n < 0$,则阶乘不存在。\n",
22 | "- 如果$n = 0$,则$0! = 1$(这是一个数学定义)。\n",
23 | "- 如果$n > 0$,则阶乘的计算公式为:\n",
24 | "\n",
25 | " $$\n",
26 | " n! = 1 \\times 2 \\times 3 \\times \\dots \\times n\n",
27 | " $$\n",
28 | "\n",
29 | "### 代码流程\n",
30 | "\n",
31 | "1. **输入处理与初始化**:代码首先从用户获取一个整数输入,并将阶乘结果变量`factorial`初始化为$1$。\n",
32 | " \n",
33 | "2. **条件判断**: \n",
34 | " - 如果输入的是负数,代码输出“负数没有阶乘”。\n",
35 | " - 如果输入的是零,则根据定义直接输出结果为$1$。\n",
36 | " - 如果输入的是正整数$n$,代码使用`for`循环计算阶乘,从$1$到$n$依次相乘,得到$n!$的值。\n",
37 | "\n",
38 | "3. **输出结果**:代码最终将计算得到的阶乘值显示给用户。\n",
39 | "\n",
40 | "### 总结\n",
41 | "\n",
42 | "该代码通过条件判断和循环结构完成了阶乘计算。阶乘在数学中用于排列、组合及概率计算,因此具有广泛的应用价值。代码设计考虑了不同输入情况,确保了程序的健壮性。"
43 | ]
44 | },
45 | {
46 | "cell_type": "markdown",
47 | "id": "b027fe46-03ae-4f39-8561-02e12041fd9d",
48 | "metadata": {},
49 | "source": [
50 | "## 计算阶乘的函数"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": 1,
56 | "id": "e20acf86-fd29-4a09-a6e3-8d74e5cf48d0",
57 | "metadata": {},
58 | "outputs": [
59 | {
60 | "name": "stdin",
61 | "output_type": "stream",
62 | "text": [
63 | "Enter an integer: 10\n"
64 | ]
65 | }
66 | ],
67 | "source": [
68 | "num = int(input(\"Enter an integer: \")) # 输入一个整数"
69 | ]
70 | },
71 | {
72 | "cell_type": "code",
73 | "execution_count": 2,
74 | "id": "add8647a-e04a-4b15-b1af-7d89f7615a9d",
75 | "metadata": {},
76 | "outputs": [],
77 | "source": [
78 | "factorial = 1 # 初始化阶乘结果为1"
79 | ]
80 | },
81 | {
82 | "cell_type": "markdown",
83 | "id": "535e4b0c-1caf-4953-9e3d-b9169bab77ae",
84 | "metadata": {},
85 | "source": [
86 | "## 检查输入的整数是负数、零还是正数并计算阶乘"
87 | ]
88 | },
89 | {
90 | "cell_type": "code",
91 | "execution_count": 3,
92 | "id": "037858fb-e07e-4345-a44a-8c6ec21bf5aa",
93 | "metadata": {},
94 | "outputs": [
95 | {
96 | "name": "stdout",
97 | "output_type": "stream",
98 | "text": [
99 | "The factorial of 10 is 3628800\n"
100 | ]
101 | }
102 | ],
103 | "source": [
104 | "if num < 0: # 如果输入的是负数\n",
105 | " print(\"Factorial does not exist for negative numbers\") # 输出负数没有阶乘\n",
106 | "elif num == 0: # 如果输入的是0\n",
107 | " print(\"The factorial of 0 is \", factorial) # 输出0的阶乘为1\n",
108 | "else: # 如果输入的是正数\n",
109 | " for i in range(1, num + 1): # 循环计算阶乘\n",
110 | " factorial = factorial * i # 累乘计算阶乘\n",
111 | " print(\"The factorial of\", num, \"is\", factorial) # 输出正整数的阶乘结果"
112 | ]
113 | },
114 | {
115 | "cell_type": "code",
116 | "execution_count": null,
117 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
118 | "metadata": {},
119 | "outputs": [],
120 | "source": []
121 | }
122 | ],
123 | "metadata": {
124 | "kernelspec": {
125 | "display_name": "Python 3 (ipykernel)",
126 | "language": "python",
127 | "name": "python3"
128 | },
129 | "language_info": {
130 | "codemirror_mode": {
131 | "name": "ipython",
132 | "version": 3
133 | },
134 | "file_extension": ".py",
135 | "mimetype": "text/x-python",
136 | "name": "python",
137 | "nbconvert_exporter": "python",
138 | "pygments_lexer": "ipython3",
139 | "version": "3.12.7"
140 | }
141 | },
142 | "nbformat": 4,
143 | "nbformat_minor": 5
144 | }
145 |
--------------------------------------------------------------------------------
/Book3_Ch02_Python_Codes/Bk3_Ch02_03.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 02\n",
9 | "\n",
10 | "# 累计乘积\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "b5037569-0d80-48cb-8814-032a0f94bf73",
17 | "metadata": {},
18 | "source": [
19 | "该代码使用`numpy`库生成一个从$1$到$10$的等间距数组,并计算其累积积。累积积是指从数组开头依次将每个元素相乘,逐步计算出各个位置上的连乘结果,形成新的数组。\n",
20 | "\n",
21 | "### 代码细节\n",
22 | "\n",
23 | "1. **生成等间距数组**:`np.linspace(1, 10, 10)`生成一个数组$a_i$,从$1.0$到$10.0$共包含$10$个元素,形成以下数组:\n",
24 | "\n",
25 | " $$\n",
26 | " a_i = [1.0, 2.0, 3.0, \\dots, 10.0]\n",
27 | " $$\n",
28 | "\n",
29 | "2. **计算累积积**:使用`np.cumprod(a_i)`对数组$a_i$计算累积积,即从第一个元素开始依次累乘直到当前位置,构成一个新的数组$a_i\\_cumprod$。累积积的第$n$个元素定义为前$n$个元素的乘积:\n",
30 | "\n",
31 | " $$\n",
32 | " a_i\\_cumprod[n] = \\prod_{k=1}^{n} a_i[k]\n",
33 | " $$\n",
34 | "\n",
35 | " 例如,累积积的前几项结果为:\n",
36 | "\n",
37 | " $$\n",
38 | " a_i\\_cumprod = [1.0, 2.0, 6.0, 24.0, \\dots, 3628800.0]\n",
39 | " $$\n",
40 | "\n",
41 | "3. **输出设置**:为防止大数值以科学计数法显示,代码使用`np.set_printoptions(suppress=True)`确保输出以普通小数形式显示。\n",
42 | "\n",
43 | "### 总结\n",
44 | "\n",
45 | "通过该代码,我们可以轻松地计算数组的累积积,这在许多计算和建模场景中非常有用,例如累乘关系、概率模型等。最终输出的数组$a_i\\_cumprod$展示了累积乘积的逐步计算过程。"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "id": "d3a1b6fa-2a14-4dc8-be95-4b1066599f37",
51 | "metadata": {},
52 | "source": [
53 | "## 生成等间距数组并计算其累计乘积"
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": 1,
59 | "id": "b00f27e5-5dae-4bd4-8b25-ca7ce6d53478",
60 | "metadata": {},
61 | "outputs": [],
62 | "source": [
63 | "import numpy as np # 导入numpy库"
64 | ]
65 | },
66 | {
67 | "cell_type": "code",
68 | "execution_count": 2,
69 | "id": "74ac1f4e-5964-4be3-81fe-2a5734f1d40b",
70 | "metadata": {},
71 | "outputs": [
72 | {
73 | "name": "stdout",
74 | "output_type": "stream",
75 | "text": [
76 | "[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]\n"
77 | ]
78 | }
79 | ],
80 | "source": [
81 | "a_i = np.linspace(1, 10, 10) # 创建一个从1到10等间距的数组,共10个元素\n",
82 | "print(a_i) # 输出生成的数组a_i"
83 | ]
84 | },
85 | {
86 | "cell_type": "code",
87 | "execution_count": 3,
88 | "id": "4951aa62-327b-4008-9c61-ab51457d996d",
89 | "metadata": {},
90 | "outputs": [
91 | {
92 | "name": "stdout",
93 | "output_type": "stream",
94 | "text": [
95 | "[ 1. 2. 6. 24. 120. 720. 5040. 40320.\n",
96 | " 362880. 3628800.]\n"
97 | ]
98 | }
99 | ],
100 | "source": [
101 | "a_i_cumprod = np.cumprod(a_i) # 计算数组a_i的累积积\n",
102 | "np.set_printoptions(suppress=True) # 设置打印选项,避免科学计数法显示\n",
103 | "print(a_i_cumprod) # 输出累积积结果"
104 | ]
105 | },
106 | {
107 | "cell_type": "code",
108 | "execution_count": null,
109 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
110 | "metadata": {},
111 | "outputs": [],
112 | "source": []
113 | },
114 | {
115 | "cell_type": "code",
116 | "execution_count": null,
117 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
118 | "metadata": {},
119 | "outputs": [],
120 | "source": []
121 | }
122 | ],
123 | "metadata": {
124 | "kernelspec": {
125 | "display_name": "Python 3 (ipykernel)",
126 | "language": "python",
127 | "name": "python3"
128 | },
129 | "language_info": {
130 | "codemirror_mode": {
131 | "name": "ipython",
132 | "version": 3
133 | },
134 | "file_extension": ".py",
135 | "mimetype": "text/x-python",
136 | "name": "python",
137 | "nbconvert_exporter": "python",
138 | "pygments_lexer": "ipython3",
139 | "version": "3.12.7"
140 | }
141 | },
142 | "nbformat": 4,
143 | "nbformat_minor": 5
144 | }
145 |
--------------------------------------------------------------------------------
/Book3_Ch02_Python_Codes/Bk3_Ch02_04.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 02\n",
9 | "\n",
10 | "# 除法\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "00f9f3f6-3235-4b03-9510-fd68c8bdbd0a",
17 | "metadata": {},
18 | "source": [
19 | "该代码计算两个数字之间的除法并输出结果。代码首先定义了两个数,$6$和$3$,分别赋值给`num1`和`num2`,然后计算除法结果,即$6 \\div 3$,并将结果存储在`division`变量中。 \n",
20 | "\n",
21 | "### 代码细节\n",
22 | "\n",
23 | "1. **除法计算**:代码执行$6 \\div 3$,其计算公式为:\n",
24 | "\n",
25 | " $$\n",
26 | " \\text{division} = \\frac{\\text{num1}}{\\text{num2}} = \\frac{6}{3} = 2\n",
27 | " $$\n",
28 | "\n",
29 | " 该计算得到的商为$2$。\n",
30 | "\n",
31 | "2. **结果显示**:代码使用格式化字符串将除法运算的结果输出为“`The division of 6 over 3 is 2`”。\n",
32 | "\n",
33 | "### 总结\n",
34 | "\n",
35 | "代码简单演示了基本的除法运算,并展示如何使用格式化字符串输出计算结果。此过程适用于基本的数值计算场景,尤其是在显示两个数的商时。"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "id": "e5f9cfd9-fbd7-4efe-9e72-2086b8045f91",
41 | "metadata": {},
42 | "source": [
43 | "## 计算两个数字的除法并显示结果"
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": 1,
49 | "id": "57232dac-bada-452b-87b3-450fd3020742",
50 | "metadata": {},
51 | "outputs": [],
52 | "source": [
53 | "num1 = 6 # 定义第一个数字\n",
54 | "num2 = 3 # 定义第二个数字"
55 | ]
56 | },
57 | {
58 | "cell_type": "markdown",
59 | "id": "9630d233-8234-4e60-b177-01f237ecbcda",
60 | "metadata": {},
61 | "source": [
62 | "## 计算两个数字的除法结果"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": 2,
68 | "id": "1e3494ff-9393-4d8a-8531-f64bb1bbf7a3",
69 | "metadata": {},
70 | "outputs": [],
71 | "source": [
72 | "division = num1 / num2 # 计算num1除以num2的结果"
73 | ]
74 | },
75 | {
76 | "cell_type": "markdown",
77 | "id": "1fbe2685-cd10-4df6-b72e-333aa39b1804",
78 | "metadata": {},
79 | "source": [
80 | "## 显示计算结果"
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": 3,
86 | "id": "b6e2cc58-b511-42ed-be74-43cde1fb02ef",
87 | "metadata": {},
88 | "outputs": [
89 | {
90 | "name": "stdout",
91 | "output_type": "stream",
92 | "text": [
93 | "The division of 6 over 3 is 2.0\n"
94 | ]
95 | }
96 | ],
97 | "source": [
98 | "print('The division of {0} over {1} is {2}'.format(num1, num2, division)) # 输出除法结果"
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": null,
104 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
105 | "metadata": {},
106 | "outputs": [],
107 | "source": []
108 | },
109 | {
110 | "cell_type": "code",
111 | "execution_count": null,
112 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
113 | "metadata": {},
114 | "outputs": [],
115 | "source": []
116 | }
117 | ],
118 | "metadata": {
119 | "kernelspec": {
120 | "display_name": "Python 3 (ipykernel)",
121 | "language": "python",
122 | "name": "python3"
123 | },
124 | "language_info": {
125 | "codemirror_mode": {
126 | "name": "ipython",
127 | "version": 3
128 | },
129 | "file_extension": ".py",
130 | "mimetype": "text/x-python",
131 | "name": "python",
132 | "nbconvert_exporter": "python",
133 | "pygments_lexer": "ipython3",
134 | "version": "3.12.7"
135 | }
136 | },
137 | "nbformat": 4,
138 | "nbformat_minor": 5
139 | }
140 |
--------------------------------------------------------------------------------
/Book3_Ch02_Python_Codes/Bk3_Ch02_05.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 02\n",
9 | "\n",
10 | "# 求余\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "c1567b7e-abdf-4ec0-b268-cbf7cfee4cb6",
17 | "metadata": {},
18 | "source": [
19 | "该代码计算两个数字之间的余数并输出结果。首先定义了两个数$7$和$2$,分别赋值给变量`num1`和`num2`,然后使用模运算符(`%`)计算余数。模运算是整数除法的一部分,它返回整数除法后的剩余部分。\n",
20 | "\n",
21 | "### 代码细节\n",
22 | "\n",
23 | "1. **余数计算**:在模运算中,$a \\mod b$的结果是$a$除以$b$后的余数。此代码计算$7 \\mod 2$,计算如下:\n",
24 | "\n",
25 | " $$\n",
26 | " \\text{remainder} = \\text{num1} \\mod \\text{num2} = 7 \\mod 2 = 1\n",
27 | " $$\n",
28 | "\n",
29 | " 因为$7$除以$2$的商为$3$,余数为$1$。\n",
30 | "\n",
31 | "2. **结果显示**:代码使用格式化字符串输出结果,将计算结果表示为“`The remainder of 7 over 2 is 1`”。\n",
32 | "\n",
33 | "### 总结\n",
34 | "\n",
35 | "该代码演示了模运算的应用,计算出两个数字的余数。模运算在编程中很常见,用于确定整数的奇偶性、周期性计算以及分配问题中,是一种基本的算术运算。"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "id": "cd99dc60-1ad1-4c16-84f3-9d141a61171e",
41 | "metadata": {},
42 | "source": [
43 | "## 计算两个数字的余数并显示结果"
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": 1,
49 | "id": "eb014ef9-72a8-4e73-972c-b150e8d5c8c2",
50 | "metadata": {},
51 | "outputs": [],
52 | "source": [
53 | "num1 = 7 # 定义第一个数字"
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": 2,
59 | "id": "9a0d06fe-6906-4e74-97fe-3c0cce1a7811",
60 | "metadata": {},
61 | "outputs": [],
62 | "source": [
63 | "num2 = 2 # 定义第二个数字"
64 | ]
65 | },
66 | {
67 | "cell_type": "markdown",
68 | "id": "96b08cd2-2067-45f6-8c21-64295a6d4dbd",
69 | "metadata": {},
70 | "source": [
71 | "## 计算两个数字的余数"
72 | ]
73 | },
74 | {
75 | "cell_type": "code",
76 | "execution_count": 3,
77 | "id": "97437e23-1584-4315-bcd8-02cfe0a1c78b",
78 | "metadata": {},
79 | "outputs": [],
80 | "source": [
81 | "remainder = num1 % num2 # 计算num1除以num2的余数"
82 | ]
83 | },
84 | {
85 | "cell_type": "markdown",
86 | "id": "69726a14-fe5a-4777-a89a-b5988dc0f66d",
87 | "metadata": {},
88 | "source": [
89 | "## 显示计算结果"
90 | ]
91 | },
92 | {
93 | "cell_type": "code",
94 | "execution_count": 4,
95 | "id": "a075b5bd-a9d5-40dc-b3e9-c12dd16cdd68",
96 | "metadata": {},
97 | "outputs": [
98 | {
99 | "name": "stdout",
100 | "output_type": "stream",
101 | "text": [
102 | "The remainder of 7 over 2 is 1\n"
103 | ]
104 | }
105 | ],
106 | "source": [
107 | "print('The remainder of {0} over {1} is {2}'.format(num1, num2, remainder)) # 输出余数结果"
108 | ]
109 | },
110 | {
111 | "cell_type": "code",
112 | "execution_count": null,
113 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
114 | "metadata": {},
115 | "outputs": [],
116 | "source": []
117 | },
118 | {
119 | "cell_type": "code",
120 | "execution_count": null,
121 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
122 | "metadata": {},
123 | "outputs": [],
124 | "source": []
125 | }
126 | ],
127 | "metadata": {
128 | "kernelspec": {
129 | "display_name": "Python 3 (ipykernel)",
130 | "language": "python",
131 | "name": "python3"
132 | },
133 | "language_info": {
134 | "codemirror_mode": {
135 | "name": "ipython",
136 | "version": 3
137 | },
138 | "file_extension": ".py",
139 | "mimetype": "text/x-python",
140 | "name": "python",
141 | "nbconvert_exporter": "python",
142 | "pygments_lexer": "ipython3",
143 | "version": "3.12.7"
144 | }
145 | },
146 | "nbformat": 4,
147 | "nbformat_minor": 5
148 | }
149 |
--------------------------------------------------------------------------------
/Book3_Ch02_Python_Codes/Bk3_Ch02_06.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 02\n",
9 | "\n",
10 | "# 矩阵标量乘法\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "c77654c5-82c0-49e9-ae19-701d7f63e454",
17 | "metadata": {},
18 | "source": [
19 | "该代码使用`numpy`库定义了一个列向量、一个行向量和一个矩阵,并分别对它们执行标量乘法操作。标量乘法是一种基本的线性代数运算,即将向量或矩阵的每个元素与同一数相乘。\n",
20 | "\n",
21 | "### 代码细节\n",
22 | "\n",
23 | "1. **列向量标量乘法**:定义列向量\n",
24 | "\n",
25 | " $$\n",
26 | " a_\\text{col} = \\begin{bmatrix} 1 \\\\ 2 \\\\ 3 \\end{bmatrix}\n",
27 | " $$\n",
28 | "\n",
29 | " 将该向量与标量$2$相乘,得到新的列向量\n",
30 | "\n",
31 | " $$\n",
32 | " b_\\text{col} = 2 \\times a_\\text{col} = \\begin{bmatrix} 2 \\\\ 4 \\\\ 6 \\end{bmatrix}\n",
33 | " $$\n",
34 | "\n",
35 | "2. **行向量标量乘法**:定义行向量\n",
36 | "\n",
37 | " $$\n",
38 | " a_\\text{row} = \\begin{bmatrix} 1 & 2 & 3 \\end{bmatrix}\n",
39 | " $$\n",
40 | "\n",
41 | " 将该向量与标量$2$相乘,结果为\n",
42 | "\n",
43 | " $$\n",
44 | " b_\\text{row} = 2 \\times a_\\text{row} = \\begin{bmatrix} 2 & 4 & 6 \\end{bmatrix}\n",
45 | " $$\n",
46 | "\n",
47 | "3. **矩阵标量乘法**:定义矩阵\n",
48 | "\n",
49 | " $$\n",
50 | " A = \\begin{bmatrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\end{bmatrix}\n",
51 | " $$\n",
52 | "\n",
53 | " 通过将每个元素与$2$相乘,得到新矩阵\n",
54 | "\n",
55 | " $$\n",
56 | " B = 2 \\times A = \\begin{bmatrix} 2 & 4 & 6 \\\\ 8 & 10 & 12 \\end{bmatrix}\n",
57 | " $$\n",
58 | "\n",
59 | "### 总结\n",
60 | "\n",
61 | "这段代码展示了列向量、行向量和矩阵的标量乘法。通过这种操作,可以将向量和矩阵中的每个元素同时放大或缩小,这在数据缩放、线性变换和各种线性代数运算中具有广泛应用。"
62 | ]
63 | },
64 | {
65 | "cell_type": "markdown",
66 | "id": "266b0921-1792-4003-ac95-409826a1dcce",
67 | "metadata": {},
68 | "source": [
69 | "## 定义并操作列向量"
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": 1,
75 | "id": "754d4f7e-c422-405c-96a4-27f492433f26",
76 | "metadata": {},
77 | "outputs": [],
78 | "source": [
79 | "import numpy as np # 导入numpy库"
80 | ]
81 | },
82 | {
83 | "cell_type": "code",
84 | "execution_count": 2,
85 | "id": "197ad134-7e1a-453e-b30b-8138f1d63e19",
86 | "metadata": {},
87 | "outputs": [
88 | {
89 | "data": {
90 | "text/plain": [
91 | "array([[1],\n",
92 | " [2],\n",
93 | " [3]])"
94 | ]
95 | },
96 | "execution_count": 2,
97 | "metadata": {},
98 | "output_type": "execute_result"
99 | }
100 | ],
101 | "source": [
102 | "a_col = np.array([[1], [2], [3]]) # 定义列向量a_col\n",
103 | "a_col # 输出列向量a_col"
104 | ]
105 | },
106 | {
107 | "cell_type": "code",
108 | "execution_count": 3,
109 | "id": "9c631466-e075-47a5-8e96-747fa1516cc8",
110 | "metadata": {},
111 | "outputs": [
112 | {
113 | "data": {
114 | "text/plain": [
115 | "array([[2],\n",
116 | " [4],\n",
117 | " [6]])"
118 | ]
119 | },
120 | "execution_count": 3,
121 | "metadata": {},
122 | "output_type": "execute_result"
123 | }
124 | ],
125 | "source": [
126 | "b_col = 2 * a_col # 将列向量a_col乘以2得到新列向量b_col\n",
127 | "b_col # 输出新列向量b_col"
128 | ]
129 | },
130 | {
131 | "cell_type": "markdown",
132 | "id": "c8022796-f6c6-45f9-a27f-2d77eeca5e39",
133 | "metadata": {},
134 | "source": [
135 | "## 定义并操作行向量"
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": 4,
141 | "id": "ab437155-59c7-4253-a3a3-ecccbf9e1dad",
142 | "metadata": {},
143 | "outputs": [
144 | {
145 | "data": {
146 | "text/plain": [
147 | "array([[1, 2, 3]])"
148 | ]
149 | },
150 | "execution_count": 4,
151 | "metadata": {},
152 | "output_type": "execute_result"
153 | }
154 | ],
155 | "source": [
156 | "a_row = np.array([[1, 2, 3]]) # 定义行向量a_row\n",
157 | "a_row # 输出行向量a_row"
158 | ]
159 | },
160 | {
161 | "cell_type": "code",
162 | "execution_count": 5,
163 | "id": "d3519acb-6378-4531-8a62-06fb91819a28",
164 | "metadata": {},
165 | "outputs": [
166 | {
167 | "data": {
168 | "text/plain": [
169 | "array([[2, 4, 6]])"
170 | ]
171 | },
172 | "execution_count": 5,
173 | "metadata": {},
174 | "output_type": "execute_result"
175 | }
176 | ],
177 | "source": [
178 | "b_row = 2 * a_row # 将行向量a_row乘以2得到新行向量b_row\n",
179 | "b_row # 输出新行向量b_row"
180 | ]
181 | },
182 | {
183 | "cell_type": "markdown",
184 | "id": "77599f82-bb49-4f14-af94-bdcfc17037f8",
185 | "metadata": {},
186 | "source": [
187 | "## 定义并操作矩阵"
188 | ]
189 | },
190 | {
191 | "cell_type": "code",
192 | "execution_count": 6,
193 | "id": "71b91160-25fc-4c3c-980d-a4d454f74928",
194 | "metadata": {},
195 | "outputs": [
196 | {
197 | "data": {
198 | "text/plain": [
199 | "array([[1, 2, 3],\n",
200 | " [4, 5, 6]])"
201 | ]
202 | },
203 | "execution_count": 6,
204 | "metadata": {},
205 | "output_type": "execute_result"
206 | }
207 | ],
208 | "source": [
209 | "A = np.array([[1, 2, 3], # 定义矩阵A\n",
210 | " [4, 5, 6]])\n",
211 | "A # 输出矩阵A"
212 | ]
213 | },
214 | {
215 | "cell_type": "code",
216 | "execution_count": 7,
217 | "id": "e3416055-f508-4037-8202-921d2a5772e9",
218 | "metadata": {},
219 | "outputs": [
220 | {
221 | "data": {
222 | "text/plain": [
223 | "array([[ 2, 4, 6],\n",
224 | " [ 8, 10, 12]])"
225 | ]
226 | },
227 | "execution_count": 7,
228 | "metadata": {},
229 | "output_type": "execute_result"
230 | }
231 | ],
232 | "source": [
233 | "B = 2 * A # 将矩阵A乘以2得到新矩阵B\n",
234 | "B # 输出新矩阵B"
235 | ]
236 | },
237 | {
238 | "cell_type": "code",
239 | "execution_count": null,
240 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
241 | "metadata": {},
242 | "outputs": [],
243 | "source": []
244 | }
245 | ],
246 | "metadata": {
247 | "kernelspec": {
248 | "display_name": "Python 3 (ipykernel)",
249 | "language": "python",
250 | "name": "python3"
251 | },
252 | "language_info": {
253 | "codemirror_mode": {
254 | "name": "ipython",
255 | "version": 3
256 | },
257 | "file_extension": ".py",
258 | "mimetype": "text/x-python",
259 | "name": "python",
260 | "nbconvert_exporter": "python",
261 | "pygments_lexer": "ipython3",
262 | "version": "3.12.7"
263 | }
264 | },
265 | "nbformat": 4,
266 | "nbformat_minor": 5
267 | }
268 |
--------------------------------------------------------------------------------
/Book3_Ch02_Python_Codes/Bk3_Ch02_08.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 02\n",
9 | "\n",
10 | "# 逐项积\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "3b30f4cb-779b-48b9-9205-457973d012ca",
17 | "metadata": {},
18 | "source": [
19 | "该代码使用`numpy`库计算了两个行向量和两个矩阵的逐元素乘积(element-wise product),即对同维度向量或矩阵的对应位置的元素逐一相乘,得到一个新的向量或矩阵。\n",
20 | "\n",
21 | "### 代码细节\n",
22 | "\n",
23 | "1. **行向量逐元素乘积**:\n",
24 | " - 定义了两个行向量 $a = [1, 2, 3]$ 和 $b = [4, 5, 6]$。\n",
25 | " - 计算$a$和$b$的逐元素乘积,逐元素乘积的公式为:\n",
26 | "\n",
27 | " $$\n",
28 | " a\\_times\\_b = [a[0] \\times b[0], a[1] \\times b[1], a[2] \\times b[2]] = [1 \\times 4, 2 \\times 5, 3 \\times 6] = [4, 10, 18]\n",
29 | " $$\n",
30 | "\n",
31 | " - 结果为向量$[4, 10, 18]$,表示两个行向量在各个位置上相乘的结果。\n",
32 | "\n",
33 | "2. **矩阵逐元素乘积**:\n",
34 | " - 定义矩阵\n",
35 | "\n",
36 | " $$\n",
37 | " A = \\begin{bmatrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\end{bmatrix}\n",
38 | " $$\n",
39 | "\n",
40 | " 和矩阵\n",
41 | "\n",
42 | " $$\n",
43 | " B = \\begin{bmatrix} 1 & 2 & 3 \\\\ -1 & 0 & 1 \\end{bmatrix}\n",
44 | " $$\n",
45 | "\n",
46 | " - 逐元素乘积通过将矩阵$A$和$B$的对应元素分别相乘,得到新矩阵$A\\_times\\_B$:\n",
47 | "\n",
48 | " $$\n",
49 | " A\\_times\\_B = \\begin{bmatrix} A[0][0] \\times B[0][0] & A[0][1] \\times B[0][1] & A[0][2] \\times B[0][2] \\\\ A[1][0] \\times B[1][0] & A[1][1] \\times B[1][1] & A[1][2] \\times B[1][2] \\end{bmatrix} = \\begin{bmatrix} 1 \\times 1 & 2 \\times 2 & 3 \\times 3 \\\\ 4 \\times -1 & 5 \\times 0 & 6 \\times 1 \\end{bmatrix} = \\begin{bmatrix} 1 & 4 & 9 \\\\ -4 & 0 & 6 \\end{bmatrix}\n",
50 | " $$\n",
51 | "\n",
52 | " - 结果矩阵$A\\_times\\_B$为$\\begin{bmatrix} 1 & 4 & 9 \\\\ -4 & 0 & 6 \\end{bmatrix}$。\n",
53 | "\n",
54 | "### 总结\n",
55 | "\n",
56 | "此代码演示了行向量和矩阵的逐元素乘积计算。逐元素乘积广泛用于神经网络中的损失计算、矩阵处理、以及数据操作中的逐项相乘计算,是数值运算中常用的基本操作。"
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "id": "e31c80e8-2306-4a5e-8eb1-be2ec929bde7",
62 | "metadata": {},
63 | "source": [
64 | "## 行向量的逐元素乘积"
65 | ]
66 | },
67 | {
68 | "cell_type": "code",
69 | "execution_count": 1,
70 | "id": "f880cefe-d9c7-48d4-8b89-d1de27ba1876",
71 | "metadata": {},
72 | "outputs": [],
73 | "source": [
74 | "import numpy as np # 导入numpy库"
75 | ]
76 | },
77 | {
78 | "cell_type": "code",
79 | "execution_count": 2,
80 | "id": "023a189b-873e-4087-a762-83a905c6a2dd",
81 | "metadata": {},
82 | "outputs": [
83 | {
84 | "data": {
85 | "text/plain": [
86 | "array([[1, 2, 3]])"
87 | ]
88 | },
89 | "execution_count": 2,
90 | "metadata": {},
91 | "output_type": "execute_result"
92 | }
93 | ],
94 | "source": [
95 | "a = np.array([[1, 2, 3]]) # 定义行向量a\n",
96 | "a # 输出行向量a"
97 | ]
98 | },
99 | {
100 | "cell_type": "code",
101 | "execution_count": 3,
102 | "id": "3973de60-41b6-487c-aff9-42413fc69446",
103 | "metadata": {},
104 | "outputs": [
105 | {
106 | "data": {
107 | "text/plain": [
108 | "array([[4, 5, 6]])"
109 | ]
110 | },
111 | "execution_count": 3,
112 | "metadata": {},
113 | "output_type": "execute_result"
114 | }
115 | ],
116 | "source": [
117 | "b = np.array([[4, 5, 6]]) # 定义行向量b\n",
118 | "b # 输出行向量b"
119 | ]
120 | },
121 | {
122 | "cell_type": "code",
123 | "execution_count": 4,
124 | "id": "e1a47587-7f42-499d-8be1-7da3e5ad6f31",
125 | "metadata": {},
126 | "outputs": [
127 | {
128 | "data": {
129 | "text/plain": [
130 | "array([[ 4, 10, 18]])"
131 | ]
132 | },
133 | "execution_count": 4,
134 | "metadata": {},
135 | "output_type": "execute_result"
136 | }
137 | ],
138 | "source": [
139 | "a_times_b = a * b # 计算行向量a和b的逐元素乘积\n",
140 | "a_times_b # 输出行向量的逐元素乘积结果"
141 | ]
142 | },
143 | {
144 | "cell_type": "markdown",
145 | "id": "0293493a-7abd-4b3d-9a35-f78892dd6d7e",
146 | "metadata": {},
147 | "source": [
148 | "## 矩阵的逐元素乘积"
149 | ]
150 | },
151 | {
152 | "cell_type": "code",
153 | "execution_count": 5,
154 | "id": "ccb53aa5-25ee-47da-8b4f-915e41c8c355",
155 | "metadata": {},
156 | "outputs": [
157 | {
158 | "data": {
159 | "text/plain": [
160 | "array([[1, 2, 3],\n",
161 | " [4, 5, 6]])"
162 | ]
163 | },
164 | "execution_count": 5,
165 | "metadata": {},
166 | "output_type": "execute_result"
167 | }
168 | ],
169 | "source": [
170 | "A = np.array([[1, 2, 3], # 定义矩阵A\n",
171 | " [4, 5, 6]])\n",
172 | "A # 输出矩阵A"
173 | ]
174 | },
175 | {
176 | "cell_type": "code",
177 | "execution_count": 6,
178 | "id": "a5ce2cbe-86a0-4417-a0dc-4b09b6fa9502",
179 | "metadata": {},
180 | "outputs": [
181 | {
182 | "data": {
183 | "text/plain": [
184 | "array([[ 1, 2, 3],\n",
185 | " [-1, 0, 1]])"
186 | ]
187 | },
188 | "execution_count": 6,
189 | "metadata": {},
190 | "output_type": "execute_result"
191 | }
192 | ],
193 | "source": [
194 | "B = np.array([[1, 2, 3], # 定义矩阵B\n",
195 | " [-1, 0, 1]])\n",
196 | "B # 输出矩阵B"
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": 7,
202 | "id": "57b8c65b-6b85-467c-ab23-4141d2fc06ab",
203 | "metadata": {},
204 | "outputs": [
205 | {
206 | "data": {
207 | "text/plain": [
208 | "array([[ 1, 4, 9],\n",
209 | " [-4, 0, 6]])"
210 | ]
211 | },
212 | "execution_count": 7,
213 | "metadata": {},
214 | "output_type": "execute_result"
215 | }
216 | ],
217 | "source": [
218 | "A_times_B = A * B # 计算矩阵A和B的逐元素乘积\n",
219 | "A_times_B # 输出矩阵的逐元素乘积结果"
220 | ]
221 | }
222 | ],
223 | "metadata": {
224 | "kernelspec": {
225 | "display_name": "Python 3 (ipykernel)",
226 | "language": "python",
227 | "name": "python3"
228 | },
229 | "language_info": {
230 | "codemirror_mode": {
231 | "name": "ipython",
232 | "version": 3
233 | },
234 | "file_extension": ".py",
235 | "mimetype": "text/x-python",
236 | "name": "python",
237 | "nbconvert_exporter": "python",
238 | "pygments_lexer": "ipython3",
239 | "version": "3.12.7"
240 | }
241 | },
242 | "nbformat": 4,
243 | "nbformat_minor": 5
244 | }
245 |
--------------------------------------------------------------------------------
/Book3_Ch02_Python_Codes/Streamlit_Bk3_Ch02_10.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | # 导入必要的库
9 | import numpy as np # 用于生成随机矩阵并进行矩阵运算
10 | import streamlit as st # 用于创建交互式Web应用
11 | import seaborn as sns # 用于绘制热力图
12 | from matplotlib import pyplot as plt # 用于生成图形
13 |
14 | # 定义函数bmatrix,将二维数组转换为LaTeX格式的矩阵
15 | def bmatrix(a):
16 | """
17 | 将NumPy数组转换为LaTeX bmatrix格式的字符串表示
18 | :param a: 输入的NumPy数组
19 | :return: LaTeX格式的bmatrix字符串
20 | """
21 | if len(a.shape) > 2: # 确保输入是二维数组
22 | raise ValueError('bmatrix can at most display two dimensions') # 超过二维时报错
23 | lines = str(a).replace('[', '').replace(']', '').splitlines() # 去掉中括号并分行
24 | rv = [r'\begin{bmatrix}'] # 起始LaTeX矩阵标记
25 | rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines] # 按行拼接元素
26 | rv += [r'\end{bmatrix}'] # 结束LaTeX矩阵标记
27 | return '\n'.join(rv) # 返回完整的LaTeX bmatrix字符串
28 |
29 | # 在侧边栏添加用户交互控件
30 | with st.sidebar:
31 | st.latex(r'C_{m\times n} = A_{m\times p} B_{p\times n}') # 显示矩阵乘法公式
32 | # 用户选择矩阵A的行数
33 | rows_A = st.slider('Number of rows in A:',
34 | min_value=1,
35 | max_value=9,
36 | value=5,
37 | step=1)
38 | # 用户选择矩阵A的列数
39 | cols_A = st.slider('Number of columns in A:',
40 | min_value=1,
41 | max_value=9,
42 | value=5,
43 | step=1)
44 | # 用户选择矩阵B的行数
45 | rows_B = st.slider('Number of rows in B:',
46 | min_value=1,
47 | max_value=9,
48 | value=5,
49 | step=1)
50 | # 用户选择矩阵B的列数
51 | cols_B = st.slider('Number of columns in B:',
52 | min_value=1,
53 | max_value=9,
54 | value=5,
55 | step=1)
56 |
57 | # 生成随机矩阵A和B
58 | A = np.random.randint(10, size=(rows_A, cols_A)) # 随机生成0到9的整数矩阵A
59 | B = np.random.randint(10, size=(rows_B, cols_B)) # 随机生成0到9的整数矩阵B
60 |
61 | # 在界面显示矩阵A和B的LaTeX格式
62 | st.latex(r'A_{m\times p} = ' + bmatrix(A)) # 显示矩阵A
63 | st.latex(r'B_{p\times n} = ' + bmatrix(B)) # 显示矩阵B
64 |
65 | # 尝试执行矩阵乘法
66 | try:
67 | # 计算矩阵C = A * B
68 | C = A @ B
69 | st.latex('C = AB = ' + bmatrix(C)) # 显示矩阵C的LaTeX格式
70 |
71 | # 创建子图,显示矩阵热力图
72 | fig, axs = plt.subplots(1, 5, figsize=(12, 3))
73 | ## 设置背景透明
74 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
75 |
76 | # 绘制矩阵A的热力图
77 | plt.sca(axs[0])
78 | ax = sns.heatmap(A, cmap='RdYlBu_r',
79 | cbar_kws={"orientation": "horizontal"},
80 | yticklabels=np.arange(1, rows_A + 1),
81 | xticklabels=np.arange(1, cols_A + 1))
82 | ax.set_aspect("equal") # 保持比例
83 | ax.set_facecolor('none') # 设置坐标轴背景为透明
84 | plt.title('$A$') # 设置标题
85 | plt.yticks(rotation=0)
86 |
87 | # 显示矩阵乘法符号
88 | plt.sca(axs[1])
89 | plt.title('$@$') # 矩阵乘法符号
90 | plt.axis('off')
91 |
92 | # 绘制矩阵B的热力图
93 | plt.sca(axs[2])
94 | ax = sns.heatmap(B, cmap='RdYlBu_r',
95 | cbar_kws={"orientation": "horizontal"},
96 | yticklabels=np.arange(1, rows_B + 1),
97 | xticklabels=np.arange(1, cols_B + 1))
98 | ax.set_aspect("equal")
99 | ax.set_facecolor('none') # 设置坐标轴背景为透明
100 | plt.title('$B$')
101 | plt.yticks(rotation=0)
102 |
103 | # 显示等号
104 | plt.sca(axs[3])
105 | plt.title('$=$') # 等号
106 | plt.axis('off')
107 |
108 | # 绘制矩阵C的热力图
109 | plt.sca(axs[4])
110 | ax = sns.heatmap(C, cmap='RdYlBu_r',
111 | cbar_kws={"orientation": "horizontal"},
112 | yticklabels=np.arange(1, rows_A + 1),
113 | xticklabels=np.arange(1, cols_B + 1))
114 | ax.set_aspect("equal")
115 | ax.set_facecolor('none') # 设置坐标轴背景为透明
116 | plt.title('$C$')
117 | plt.yticks(rotation=0)
118 |
119 | # 在界面显示热力图
120 | st.pyplot(fig)
121 |
122 | except: # 如果矩阵乘法无法进行(列数不等于行数),提示用户
123 | st.write('The number of columns of the first matrix, must equal the number of rows of the second matrix.')
124 |
--------------------------------------------------------------------------------
/Book3_Ch02_乘除__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch02_乘除__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch03_Python_Codes/Streamlit_Bk3_Ch03_03.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | # 导入所需的库
9 | import streamlit as st # 导入 Streamlit,用于创建交互式 Web 应用
10 | import matplotlib.pyplot as plt # 导入 Matplotlib,用于绘制图形
11 | from matplotlib.patches import RegularPolygon, Circle # 导入 RegularPolygon 和 Circle,用于绘制多边形和圆
12 | import numpy as np # 导入 NumPy,用于数值计算
13 |
14 | # == 第一部分:设置边数的交互滑块 ==
15 | with st.sidebar:
16 | # 创建滑块,用于用户选择多边形的边数
17 | num_vertices = st.slider(
18 | 'Number of sides of polygon:', # 滑块的描述
19 | min_value=4, # 滑块的最小值
20 | max_value=20, # 滑块的最大值
21 | step=1 # 滑块的步长
22 | )
23 |
24 | # == 第二部分:绘制多边形和内接圆、外接圆 ==
25 | fig_1, ax = plt.subplots() # 创建一个 Matplotlib 图形对象和坐标轴对象
26 | ax.set_aspect('equal') # 设置坐标轴比例相等
27 | ## 设置背景透明
28 | fig_1.patch.set_alpha(0) # 设置整个图形背景为透明
29 | ax.set_facecolor('none') # 设置坐标轴背景为透明
30 | # 绘制内接多边形
31 | hexagon_inner = RegularPolygon(
32 | (0, 0), # 多边形的中心坐标
33 | numVertices=num_vertices, # 多边形的边数
34 | radius=1, # 多边形的半径
35 | alpha=0.2, # 透明度
36 | edgecolor='0.6' # 边框颜色
37 | )
38 | ax.add_patch(hexagon_inner) # 将内接多边形添加到坐标轴
39 |
40 | # 绘制外接多边形
41 | hexagon_outer = RegularPolygon(
42 | (0, 0), # 多边形的中心坐标
43 | numVertices=num_vertices, # 多边形的边数
44 | radius=1 / np.cos(np.pi / num_vertices), # 外接多边形的半径
45 | alpha=0.2, # 透明度
46 | edgecolor='0.6' # 边框颜色
47 | )
48 | ax.add_patch(hexagon_outer) # 将外接多边形添加到坐标轴
49 |
50 | # 绘制圆
51 | circle = Circle(
52 | (0, 0), # 圆心坐标
53 | radius=1, # 圆的半径
54 | facecolor='none', # 圆的填充颜色
55 | edgecolor='0.6' # 圆的边框颜色
56 | )
57 | ax.add_patch(circle) # 将圆添加到坐标轴
58 |
59 | # 关闭坐标轴
60 | plt.axis('off')
61 |
62 | # 设置显示范围
63 | plt.xlim(-1.5, 1.5) # x 轴范围
64 | plt.ylim(-1.5, 1.5) # y 轴范围
65 | plt.show() # 显示图形
66 |
67 | # 在 Streamlit 界面中显示图形
68 | st.pyplot(fig_1)
69 |
70 | # == 第三部分:通过内接和外接多边形估算圆周率 ==
71 | # 创建多边形边数的数组
72 | n_array = np.linspace(3, num_vertices)
73 |
74 | # 计算内接多边形和外接多边形估算的 π 的上下界
75 | pi_lower_b = np.sin(np.pi / n_array) * n_array # 内接多边形的估算
76 | pi_upper_b = np.tan(np.pi / n_array) * n_array # 外接多边形的估算
77 |
78 | # 创建一个新图形对象用于绘制 π 的估算范围
79 | fig_2, ax = plt.subplots()
80 | ## 设置背景透明
81 | fig_2.patch.set_alpha(0) # 设置整个图形背景为透明
82 | ax.set_facecolor('none') # 设置坐标轴背景为透明
83 | # 添加实际的 π 作为参考线
84 | plt.axhline(y=np.pi, color='r', linestyle='-')
85 |
86 | # 绘制内接多边形和外接多边形的 π 的估算曲线
87 | plt.plot(n_array, pi_lower_b, color='b', label='Lower Bound') # 内接多边形估算曲线
88 | plt.plot(n_array, pi_upper_b, color='g', label='Upper Bound') # 外接多边形估算曲线
89 |
90 | # 填充 π 的估算范围
91 | plt.fill_between(n_array, pi_lower_b, pi_upper_b, color='#DEEAF6', label='Estimate Range')
92 |
93 | # 设置布局和标签
94 | plt.tight_layout() # 自动调整子图布局
95 | plt.xlabel('Number of sides, n') # x 轴标签
96 | plt.ylabel('Estimate of $\pi$') # y 轴标签
97 |
98 | # 设置 x 轴的范围
99 | plt.xlim((n_array.min(), n_array.max()))
100 |
101 | # 在 Streamlit 界面中显示图形
102 | st.pyplot(fig_2)
103 |
--------------------------------------------------------------------------------
/Book3_Ch03_几何__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch03_几何__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch04_Python_Codes/Bk3_Ch04_02.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 04\n",
9 | "\n",
10 | "# 代数运算\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "41c56724-a241-443c-9de3-77ca43ac2bb3",
17 | "metadata": {},
18 | "source": [
19 | "该代码使用`sympy`库创建并操作代数表达式,包括定义表达式、符号替换和表达式的值计算。首先,定义了一个三次多项式表达式:\n",
20 | "\n",
21 | "$$\n",
22 | "\\text{expr}_x = x^3 + 2x^2 - x - 2\n",
23 | "$$\n",
24 | "\n",
25 | "然后,将$x$替换为$1$来计算该表达式的具体值:\n",
26 | "\n",
27 | "$$\n",
28 | "\\text{expr}_x \\big|_{x=1} = 1^3 + 2 \\cdot 1^2 - 1 - 2 = 0\n",
29 | "$$\n",
30 | "\n",
31 | "接着,代码将表达式中的$x$替换为$\\cos(y)$,生成一个新的表达式$\\text{expr}_{\\cos y}$,表示三角函数的代数形式:\n",
32 | "\n",
33 | "$$\n",
34 | "\\text{expr}_{\\cos y} = \\cos(y)^3 + 2\\cos(y)^2 - \\cos(y) - 2\n",
35 | "$$\n",
36 | "\n",
37 | "在代码的最后部分,重新定义了符号$x$和$y$,并创建表达式$\\text{expr}_1 = x + y$,然后定义了新的符号$x_1$和$x_2$,创建表达式$\\text{expr}_2 = x_1 + x_2$。通过这种方式,代码展示了在符号表达式中如何定义、替换和重新定义符号以生成新表达式。\n",
38 | "\n",
39 | "这一过程体现了代数符号的灵活操作性,可以通过符号替换或重新定义来得到不同的表达式形式,从而实现对数学表达式的动态处理。这种符号替换和表达式生成的能力在公式推导、符号计算和解析函数构建中非常有用。"
40 | ]
41 | },
42 | {
43 | "cell_type": "markdown",
44 | "id": "2673cad2-1edd-48b9-801e-da59087e1a50",
45 | "metadata": {},
46 | "source": [
47 | "## 定义表达式并进行代入计算"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": 1,
53 | "id": "d913c630-ad07-4626-bd20-ed323772cc82",
54 | "metadata": {},
55 | "outputs": [
56 | {
57 | "data": {
58 | "text/latex": [
59 | "$\\displaystyle x^{3} + 2 x^{2} - x - 2$"
60 | ],
61 | "text/plain": [
62 | "x**3 + 2*x**2 - x - 2"
63 | ]
64 | },
65 | "execution_count": 1,
66 | "metadata": {},
67 | "output_type": "execute_result"
68 | }
69 | ],
70 | "source": [
71 | "from sympy.abc import x, y\n",
72 | "\n",
73 | "expr_x = x**3 + 2*x**2 - x - 2 # 定义表达式expr_x\n",
74 | "expr_x # 输出表达式expr_x"
75 | ]
76 | },
77 | {
78 | "cell_type": "code",
79 | "execution_count": 2,
80 | "id": "cc6f5fa2-a796-4392-9836-85de0a87d7be",
81 | "metadata": {},
82 | "outputs": [
83 | {
84 | "name": "stdout",
85 | "output_type": "stream",
86 | "text": [
87 | "0\n"
88 | ]
89 | }
90 | ],
91 | "source": [
92 | "print(expr_x.subs(x, 1)) # 将x替换为1后计算表达式值"
93 | ]
94 | },
95 | {
96 | "cell_type": "markdown",
97 | "id": "887d8a29-3ab0-40d3-824e-f891ad28b5f6",
98 | "metadata": {},
99 | "source": [
100 | "## 将表达式中的变量替换为cos(y)"
101 | ]
102 | },
103 | {
104 | "cell_type": "code",
105 | "execution_count": 3,
106 | "id": "842e7862-85bf-4bba-86ba-d4b2b8356c8a",
107 | "metadata": {},
108 | "outputs": [],
109 | "source": [
110 | "from sympy import cos"
111 | ]
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": 4,
116 | "id": "9827c100-2aa3-4bb2-b495-7cedab84311d",
117 | "metadata": {},
118 | "outputs": [
119 | {
120 | "data": {
121 | "text/latex": [
122 | "$\\displaystyle \\cos^{3}{\\left(y \\right)} + 2 \\cos^{2}{\\left(y \\right)} - \\cos{\\left(y \\right)} - 2$"
123 | ],
124 | "text/plain": [
125 | "cos(y)**3 + 2*cos(y)**2 - cos(y) - 2"
126 | ]
127 | },
128 | "execution_count": 4,
129 | "metadata": {},
130 | "output_type": "execute_result"
131 | }
132 | ],
133 | "source": [
134 | "expr_cos_y = expr_x.subs(x, cos(y)) # 将x替换为cos(y)后的新表达式expr_cos_y\n",
135 | "expr_cos_y # 输出替换后的表达式"
136 | ]
137 | },
138 | {
139 | "cell_type": "markdown",
140 | "id": "ff458584-2d65-4dd9-8df9-632247eb12ff",
141 | "metadata": {},
142 | "source": [
143 | "## 定义新符号和表达式"
144 | ]
145 | },
146 | {
147 | "cell_type": "code",
148 | "execution_count": 5,
149 | "id": "2a62dfe7-1ee6-4845-9c27-5c8be7b33c2d",
150 | "metadata": {},
151 | "outputs": [],
152 | "source": [
153 | "from sympy import symbols"
154 | ]
155 | },
156 | {
157 | "cell_type": "code",
158 | "execution_count": 6,
159 | "id": "e4869ff7-f257-4218-8736-f199c762ea9e",
160 | "metadata": {},
161 | "outputs": [
162 | {
163 | "data": {
164 | "text/latex": [
165 | "$\\displaystyle x + y$"
166 | ],
167 | "text/plain": [
168 | "x + y"
169 | ]
170 | },
171 | "execution_count": 6,
172 | "metadata": {},
173 | "output_type": "execute_result"
174 | }
175 | ],
176 | "source": [
177 | "x, y = symbols('x y') # 定义符号x和y\n",
178 | "expr_1 = x + y # 创建表达式expr_1\n",
179 | "expr_1 # 输出表达式expr_1"
180 | ]
181 | },
182 | {
183 | "cell_type": "code",
184 | "execution_count": 7,
185 | "id": "177c2c1f-eeb5-4ce2-a81f-6b6fccab480f",
186 | "metadata": {},
187 | "outputs": [],
188 | "source": [
189 | "x1, x2 = symbols('x1 x2') # 定义符号x1和x2"
190 | ]
191 | },
192 | {
193 | "cell_type": "code",
194 | "execution_count": 8,
195 | "id": "7c9af817-3743-4b24-b8e4-2c53e4cf678e",
196 | "metadata": {},
197 | "outputs": [
198 | {
199 | "data": {
200 | "text/latex": [
201 | "$\\displaystyle x_{1} + x_{2}$"
202 | ],
203 | "text/plain": [
204 | "x1 + x2"
205 | ]
206 | },
207 | "execution_count": 8,
208 | "metadata": {},
209 | "output_type": "execute_result"
210 | }
211 | ],
212 | "source": [
213 | "expr_2 = x1 + x2 # 创建表达式expr_2\n",
214 | "expr_2 # 输出表达式expr_2"
215 | ]
216 | },
217 | {
218 | "cell_type": "code",
219 | "execution_count": null,
220 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
221 | "metadata": {},
222 | "outputs": [],
223 | "source": []
224 | }
225 | ],
226 | "metadata": {
227 | "kernelspec": {
228 | "display_name": "Python 3 (ipykernel)",
229 | "language": "python",
230 | "name": "python3"
231 | },
232 | "language_info": {
233 | "codemirror_mode": {
234 | "name": "ipython",
235 | "version": 3
236 | },
237 | "file_extension": ".py",
238 | "mimetype": "text/x-python",
239 | "name": "python",
240 | "nbconvert_exporter": "python",
241 | "pygments_lexer": "ipython3",
242 | "version": "3.12.7"
243 | }
244 | },
245 | "nbformat": 4,
246 | "nbformat_minor": 5
247 | }
248 |
--------------------------------------------------------------------------------
/Book3_Ch04_Python_Codes/Bk3_Ch04_03.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 04\n",
9 | "\n",
10 | "# 处理代数式\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "dfbc8db0-55ac-4f99-8e93-09aed5b107cd",
17 | "metadata": {},
18 | "source": [
19 | "这段代码使用了SymPy库来执行符号数学运算,其功能包括定义符号变量、简化表达式、展开多项式、因式分解多项式,以及对表达式进行变量项的收集。\n",
20 | "\n",
21 | "首先,代码通过 $x, y, z = symbols('x y z')$ 定义了三个符号变量 $x, y, z$,以便后续进行符号数学操作。这些变量是符号对象,而非具体的数值变量。\n",
22 | "\n",
23 | "### 简化表达式\n",
24 | "代码定义了一个表达式 $expr_1 = \\sin^2(x) - \\cos^2(x)$,这是一个基于三角函数的表达式。根据三角恒等式:\n",
25 | "$$\\sin^2(x) - \\cos^2(x) = -\\cos(2x),$$\n",
26 | "代码可以进一步对其进行化简,但化简过程在此代码中未明确执行。\n",
27 | "\n",
28 | "### 展开多项式\n",
29 | "接下来,代码定义了一个多项式表达式 $expr_2 = (x + 1)^3$,表示 $(x + 1)$ 的三次方。如果展开该表达式,使用二项式定理:\n",
30 | "$$(x + 1)^3 = x^3 + 3x^2 + 3x + 1.$$\n",
31 | "代码中的 `expr_2` 可以用来展示多项式的原始形式和展开形式。\n",
32 | "\n",
33 | "### 因式分解多项式\n",
34 | "然后,代码定义了一个三次多项式 $expr_3 = x^3 + 2x^2 - x - 2$,并对其执行因式分解。如果手动计算,可尝试分组因式分解:\n",
35 | "$$x^3 + 2x^2 - x - 2 = (x^2 - 1)(x + 2) = (x - 1)(x + 1)(x + 2).$$\n",
36 | "代码中的表达式可以通过 SymPy 的工具自动完成类似的分解。\n",
37 | "\n",
38 | "### 收集表达式中的变量项\n",
39 | "最后一段代码定义了一个新的表达式 $expr_collected$,它将 $expr_3 - x^2 - 2x$中的 $x$ 项进行收集。表达式可展开为:\n",
40 | "$$expr_3 - x^2 - 2x = x^3 + 2x^2 - x - 2 - x^2 - 2x = x^3 + x^2 - 3x - 2.$$\n",
41 | "随后,通过 `collect` 函数,代码会将所有含 $x$ 的项分组,以便观察变量的分布或简化运算。\n",
42 | "\n",
43 | "总之,这段代码的主要目的是演示如何用符号数学方法处理表达式,包括简化、展开、因式分解和变量项收集。这些功能广泛应用于符号计算、数学建模和公式推导等领域。"
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "id": "183a5e62-97a6-4266-bf6b-a7d02881fb0f",
49 | "metadata": {},
50 | "source": [
51 | "## 导入所需的库"
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": 1,
57 | "id": "e65f651f-adb2-42e0-9e91-d5650fd5266c",
58 | "metadata": {},
59 | "outputs": [],
60 | "source": [
61 | "from sympy import * # 导入SymPy库,用于符号数学计算\n",
62 | "# 定义符号变量 x, y, z,方便进行符号运算\n",
63 | "x, y, z = symbols('x y z') # 定义符号变量"
64 | ]
65 | },
66 | {
67 | "cell_type": "markdown",
68 | "id": "28164217-da31-4749-9e91-db1325666972",
69 | "metadata": {},
70 | "source": [
71 | "## 简化数学表达式"
72 | ]
73 | },
74 | {
75 | "cell_type": "code",
76 | "execution_count": 2,
77 | "id": "e34fec06-927c-4fda-8d14-765563310995",
78 | "metadata": {},
79 | "outputs": [
80 | {
81 | "data": {
82 | "text/latex": [
83 | "$\\displaystyle \\sin^{2}{\\left(x \\right)} - \\cos^{2}{\\left(x \\right)}$"
84 | ],
85 | "text/plain": [
86 | "sin(x)**2 - cos(x)**2"
87 | ]
88 | },
89 | "execution_count": 2,
90 | "metadata": {},
91 | "output_type": "execute_result"
92 | }
93 | ],
94 | "source": [
95 | "# 定义表达式 expr_1 为 sin(x)**2 - cos(x)**2\n",
96 | "expr_1 = sin(x)**2 - cos(x)**2 # 定义表达式,表示正弦平方减去余弦平方\n",
97 | "expr_1 # 输出表达式,查看原始形式"
98 | ]
99 | },
100 | {
101 | "cell_type": "markdown",
102 | "id": "4b5261ba-9448-4bd7-ae16-d2621fa158da",
103 | "metadata": {},
104 | "source": [
105 | "## 展开多项式表达式"
106 | ]
107 | },
108 | {
109 | "cell_type": "code",
110 | "execution_count": 3,
111 | "id": "cc0fa8ed-24eb-477d-9cb4-4cdf988c1f02",
112 | "metadata": {},
113 | "outputs": [
114 | {
115 | "data": {
116 | "text/latex": [
117 | "$\\displaystyle \\left(x + 1\\right)^{3}$"
118 | ],
119 | "text/plain": [
120 | "(x + 1)**3"
121 | ]
122 | },
123 | "execution_count": 3,
124 | "metadata": {},
125 | "output_type": "execute_result"
126 | }
127 | ],
128 | "source": [
129 | "# 定义表达式 expr_2 为 (x + 1)**3\n",
130 | "expr_2 = (x + 1)**3 # 定义表达式,表示 (x+1) 的三次方\n",
131 | "expr_2 # 输出表达式,查看原始形式"
132 | ]
133 | },
134 | {
135 | "cell_type": "markdown",
136 | "id": "4efd68d1-5b35-4ada-b304-dcdcc0947759",
137 | "metadata": {},
138 | "source": [
139 | "## 将多项式分解为不可约因子"
140 | ]
141 | },
142 | {
143 | "cell_type": "code",
144 | "execution_count": 4,
145 | "id": "667aa4fd-7317-480d-b820-1a70f61abb0d",
146 | "metadata": {},
147 | "outputs": [
148 | {
149 | "data": {
150 | "text/latex": [
151 | "$\\displaystyle x^{3} + 2 x^{2} - x - 2$"
152 | ],
153 | "text/plain": [
154 | "x**3 + 2*x**2 - x - 2"
155 | ]
156 | },
157 | "execution_count": 4,
158 | "metadata": {},
159 | "output_type": "execute_result"
160 | }
161 | ],
162 | "source": [
163 | "# 定义表达式 expr_3 为 x**3 + 2*x**2 - x - 2\n",
164 | "expr_3 = x**3 + 2*x**2 - x - 2 # 定义多项式表达式\n",
165 | "expr_3 # 输出表达式,查看原始形式"
166 | ]
167 | },
168 | {
169 | "cell_type": "markdown",
170 | "id": "1676d8cf-0a7c-4316-a679-8ef71e3b91b2",
171 | "metadata": {},
172 | "source": [
173 | "## 收集表达式中公共的幂次项"
174 | ]
175 | },
176 | {
177 | "cell_type": "code",
178 | "execution_count": 5,
179 | "id": "c3015ac9-7dd9-47d3-8e6b-edd3b7b3a2d0",
180 | "metadata": {},
181 | "outputs": [
182 | {
183 | "data": {
184 | "text/latex": [
185 | "$\\displaystyle x^{3} + x^{2} - 3 x - 2$"
186 | ],
187 | "text/plain": [
188 | "x**3 + x**2 - 3*x - 2"
189 | ]
190 | },
191 | "execution_count": 5,
192 | "metadata": {},
193 | "output_type": "execute_result"
194 | }
195 | ],
196 | "source": [
197 | "# 对 expr_3 - x**2 - 2*x 表达式中的 x 项进行收集\n",
198 | "expr_collected = collect(expr_3 - x**2 - 2*x, x) # 使用 collect 函数收集表达式中的 x 项\n",
199 | "expr_collected # 输出收集后的表达式"
200 | ]
201 | }
202 | ],
203 | "metadata": {
204 | "kernelspec": {
205 | "display_name": "Python 3 (ipykernel)",
206 | "language": "python",
207 | "name": "python3"
208 | },
209 | "language_info": {
210 | "codemirror_mode": {
211 | "name": "ipython",
212 | "version": 3
213 | },
214 | "file_extension": ".py",
215 | "mimetype": "text/x-python",
216 | "name": "python",
217 | "nbconvert_exporter": "python",
218 | "pygments_lexer": "ipython3",
219 | "version": "3.12.7"
220 | }
221 | },
222 | "nbformat": 4,
223 | "nbformat_minor": 5
224 | }
225 |
--------------------------------------------------------------------------------
/Book3_Ch04_Python_Codes/Bk3_Ch04_04.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 04\n",
9 | "\n",
10 | "# 代数式转化为函数\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "88c0c570-5dec-4096-a389-ad75aba13b22",
17 | "metadata": {},
18 | "source": [
19 | "该代码使用`sympy`库创建了一个代数表达式并将其转换为可计算的Python函数。首先,定义表达式:\n",
20 | "\n",
21 | "$$\n",
22 | "\\text{expr} = x^3 + 2x^2 - x - 2\n",
23 | "$$\n",
24 | "\n",
25 | "然后,使用`lambdify`将表达式$\\text{expr}$转换为一个可以接受数值输入的Python函数$f_x$。通过这种转换,可以直接对函数$f_x$进行数值计算。代码计算了当$x=1$时的函数值:\n",
26 | "\n",
27 | "$$\n",
28 | "f_x(1) = 1^3 + 2 \\cdot 1^2 - 1 - 2 = 0\n",
29 | "$$\n",
30 | "\n",
31 | "这一过程将符号表达式转化为数值计算函数,使表达式能够用于具体值的求解或进一步的数值分析。这种符号到函数的转换对于需要多次计算表达式值的情况非常方便,例如在数值模拟和数据分析中。"
32 | ]
33 | },
34 | {
35 | "cell_type": "markdown",
36 | "id": "e816e3f3-a979-461a-bf66-f54d00a807ad",
37 | "metadata": {},
38 | "source": [
39 | "## 定义表达式并创建对应的函数"
40 | ]
41 | },
42 | {
43 | "cell_type": "code",
44 | "execution_count": 1,
45 | "id": "cbbb261f-e58b-41e0-9761-9e4c1d947190",
46 | "metadata": {},
47 | "outputs": [
48 | {
49 | "data": {
50 | "text/latex": [
51 | "$\\displaystyle x^{3} + 2 x^{2} - x - 2$"
52 | ],
53 | "text/plain": [
54 | "x**3 + 2*x**2 - x - 2"
55 | ]
56 | },
57 | "execution_count": 1,
58 | "metadata": {},
59 | "output_type": "execute_result"
60 | }
61 | ],
62 | "source": [
63 | "from sympy.abc import x, y, z\n",
64 | "\n",
65 | "expr = x**3 + 2*x**2 - x - 2 # 定义表达式expr\n",
66 | "expr # 输出表达式expr"
67 | ]
68 | },
69 | {
70 | "cell_type": "code",
71 | "execution_count": 2,
72 | "id": "5e0ce9cd-81d6-4ab2-8f14-faaae20728f2",
73 | "metadata": {},
74 | "outputs": [
75 | {
76 | "name": "stdout",
77 | "output_type": "stream",
78 | "text": [
79 | "0\n"
80 | ]
81 | }
82 | ],
83 | "source": [
84 | "from sympy.utilities.lambdify import lambdify\n",
85 | "\n",
86 | "f_x = lambdify(x, expr) # 将表达式转换为可计算的Python函数f_x\n",
87 | "\n",
88 | "print(f_x(1)) # 计算f_x在x=1时的值"
89 | ]
90 | },
91 | {
92 | "cell_type": "code",
93 | "execution_count": null,
94 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
95 | "metadata": {},
96 | "outputs": [],
97 | "source": []
98 | },
99 | {
100 | "cell_type": "code",
101 | "execution_count": null,
102 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
103 | "metadata": {},
104 | "outputs": [],
105 | "source": []
106 | }
107 | ],
108 | "metadata": {
109 | "kernelspec": {
110 | "display_name": "Python 3 (ipykernel)",
111 | "language": "python",
112 | "name": "python3"
113 | },
114 | "language_info": {
115 | "codemirror_mode": {
116 | "name": "ipython",
117 | "version": 3
118 | },
119 | "file_extension": ".py",
120 | "mimetype": "text/x-python",
121 | "name": "python",
122 | "nbconvert_exporter": "python",
123 | "pygments_lexer": "ipython3",
124 | "version": "3.12.7"
125 | }
126 | },
127 | "nbformat": 4,
128 | "nbformat_minor": 5
129 | }
130 |
--------------------------------------------------------------------------------
/Book3_Ch04_Python_Codes/Bk3_Ch04_06.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 04\n",
9 | "\n",
10 | "# 无放回组合\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "49a14f93-347c-42fc-ade2-6792329ccce3",
17 | "metadata": {},
18 | "source": [
19 | "该代码使用`itertools`库生成集合$\\{\"A\", \"B\", \"C\"\\}$中所有包含两个字母的组合。具体来说,代码调用`itertools.combinations`函数生成集合的组合,忽略元素顺序,且不允许重复。对于集合$\\{\"A\", \"B\", \"C\"\\}$,选择两个字母的组合情况为:\n",
20 | "\n",
21 | "$$\n",
22 | "(A, B), (A, C), (B, C)\n",
23 | "$$\n",
24 | "\n",
25 | "即二元组合数量为:\n",
26 | "\n",
27 | "$$\n",
28 | "\\binom{3}{2} = 3\n",
29 | "$$\n",
30 | "\n",
31 | "这展示了从三元素集合中选择两个元素的无序组合情况。代码依次输出每种组合,演示了如何从集合中生成固定大小的无重复组合,这种方法在组合数学、概率统计和数据选择中有广泛应用。"
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": 1,
37 | "id": "8f483c8e-6a80-400e-8914-e51960933df0",
38 | "metadata": {},
39 | "outputs": [
40 | {
41 | "name": "stdout",
42 | "output_type": "stream",
43 | "text": [
44 | "('A', 'B')\n",
45 | "('A', 'C')\n",
46 | "('B', 'C')\n"
47 | ]
48 | }
49 | ],
50 | "source": [
51 | "## 查找包含2个字母的所有组合\n",
52 | "import itertools\n",
53 | "\n",
54 | "letters = \"ABC\" # 定义字母集\n",
55 | "\n",
56 | "cmb = itertools.combinations(letters, 2) # 生成包含2个字母的组合\n",
57 | "\n",
58 | "for val in cmb:\n",
59 | " print(val) # 输出每一个组合\n"
60 | ]
61 | },
62 | {
63 | "cell_type": "code",
64 | "execution_count": null,
65 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
66 | "metadata": {},
67 | "outputs": [],
68 | "source": []
69 | },
70 | {
71 | "cell_type": "code",
72 | "execution_count": null,
73 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
74 | "metadata": {},
75 | "outputs": [],
76 | "source": []
77 | }
78 | ],
79 | "metadata": {
80 | "kernelspec": {
81 | "display_name": "Python 3 (ipykernel)",
82 | "language": "python",
83 | "name": "python3"
84 | },
85 | "language_info": {
86 | "codemirror_mode": {
87 | "name": "ipython",
88 | "version": 3
89 | },
90 | "file_extension": ".py",
91 | "mimetype": "text/x-python",
92 | "name": "python",
93 | "nbconvert_exporter": "python",
94 | "pygments_lexer": "ipython3",
95 | "version": "3.12.7"
96 | }
97 | },
98 | "nbformat": 4,
99 | "nbformat_minor": 5
100 | }
101 |
--------------------------------------------------------------------------------
/Book3_Ch04_Python_Codes/Bk3_Ch04_07.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 04\n",
9 | "\n",
10 | "# 无放回排列\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "18c5e2e8-0899-4890-a87f-ce1e3a9ec2b7",
17 | "metadata": {},
18 | "source": [
19 | "该代码使用`itertools`库生成集合$\\{\"A\", \"B\", \"C\"\\}$中所有包含两个元素的排列。排列不同于组合,考虑了元素的顺序,因此对于选择的每一对元素,顺序不同会产生不同的排列结果。代码调用`itertools.permutations`函数,生成不重复的排列,依次输出每种排列情况。\n",
20 | "\n",
21 | "对于集合$\\{\"A\", \"B\", \"C\"\\}$,选择两个元素的排列情况为:\n",
22 | "\n",
23 | "$$\n",
24 | "(A, B), (A, C), (B, A), (B, C), (C, A), (C, B)\n",
25 | "$$\n",
26 | "\n",
27 | "排列的数量计算公式为:\n",
28 | "\n",
29 | "$$\n",
30 | "P(3, 2) = 3 \\times 2 = 6\n",
31 | "$$\n",
32 | "\n",
33 | "这意味着在三元素集合中选择两个元素的排列总数为$6$,且每种排列都区分了顺序。该代码展示了生成特定大小排列的方法,适用于需要考虑元素顺序的排列问题和组合数学中的应用。"
34 | ]
35 | },
36 | {
37 | "cell_type": "code",
38 | "execution_count": 1,
39 | "id": "f0b88a5a-bcd7-4233-ac48-0f5759f8070e",
40 | "metadata": {},
41 | "outputs": [
42 | {
43 | "name": "stdout",
44 | "output_type": "stream",
45 | "text": [
46 | "('A', 'B')\n",
47 | "('A', 'C')\n",
48 | "('B', 'A')\n",
49 | "('B', 'C')\n",
50 | "('C', 'A')\n",
51 | "('C', 'B')\n"
52 | ]
53 | }
54 | ],
55 | "source": [
56 | "## 从3个字母中排列出所有包含2个字母的排列\n",
57 | "import itertools\n",
58 | "\n",
59 | "letters = \"ABC\" # 定义字母集\n",
60 | "\n",
61 | "per = itertools.permutations(letters, 2) # 生成包含2个字母的排列\n",
62 | "\n",
63 | "for val in per:\n",
64 | " print(val) # 输出每一个排列\n"
65 | ]
66 | },
67 | {
68 | "cell_type": "code",
69 | "execution_count": null,
70 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
71 | "metadata": {},
72 | "outputs": [],
73 | "source": []
74 | },
75 | {
76 | "cell_type": "code",
77 | "execution_count": null,
78 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
79 | "metadata": {},
80 | "outputs": [],
81 | "source": []
82 | }
83 | ],
84 | "metadata": {
85 | "kernelspec": {
86 | "display_name": "Python 3 (ipykernel)",
87 | "language": "python",
88 | "name": "python3"
89 | },
90 | "language_info": {
91 | "codemirror_mode": {
92 | "name": "ipython",
93 | "version": 3
94 | },
95 | "file_extension": ".py",
96 | "mimetype": "text/x-python",
97 | "name": "python",
98 | "nbconvert_exporter": "python",
99 | "pygments_lexer": "ipython3",
100 | "version": "3.12.7"
101 | }
102 | },
103 | "nbformat": 4,
104 | "nbformat_minor": 5
105 | }
106 |
--------------------------------------------------------------------------------
/Book3_Ch04_Python_Codes/Bk3_Ch04_08.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 04\n",
9 | "\n",
10 | "# 全排列\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "19b4c5d5-80f5-448d-8ccd-d180dcca2b0e",
17 | "metadata": {},
18 | "source": [
19 | "该代码使用`itertools`库生成字母集合$\\{\"A\", \"B\", \"C\"\\}$的所有可能排列。具体来说,`itertools.permutations`函数生成集合中所有元素的全排列,并将不同顺序的排列视为不同的结果。对于包含三个元素的集合,排列的总数可以通过公式$P(n, n) = n!$计算,其中$n$为元素数量。因此,对于$n = 3$,排列总数为\n",
20 | "\n",
21 | "$$\n",
22 | "3! = 6\n",
23 | "$$\n",
24 | "\n",
25 | "即六种排列组合:\n",
26 | "\n",
27 | "$$\n",
28 | "(A, B, C), (A, C, B), (B, A, C), (B, C, A), (C, A, B), (C, B, A)\n",
29 | "$$\n",
30 | "\n",
31 | "代码依次输出这些排列,展示了如何生成所有元素的排列组合,这在需要考虑顺序的排列问题中具有广泛应用,例如组合数学和概率计算。"
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": 1,
37 | "id": "6fc99140-fb5b-4335-8bd6-0951c998ca3b",
38 | "metadata": {},
39 | "outputs": [
40 | {
41 | "name": "stdout",
42 | "output_type": "stream",
43 | "text": [
44 | "('A', 'B', 'C')\n",
45 | "('A', 'C', 'B')\n",
46 | "('B', 'A', 'C')\n",
47 | "('B', 'C', 'A')\n",
48 | "('C', 'A', 'B')\n",
49 | "('C', 'B', 'A')\n"
50 | ]
51 | }
52 | ],
53 | "source": [
54 | "## 排列所有3个字母的组合\n",
55 | "import itertools\n",
56 | "\n",
57 | "letters = \"ABC\" # 定义字母集\n",
58 | "\n",
59 | "per = itertools.permutations(letters) # 生成包含所有3个字母的排列\n",
60 | "\n",
61 | "for val in per:\n",
62 | " print(val) # 输出每一个排列\n"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": null,
68 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
69 | "metadata": {},
70 | "outputs": [],
71 | "source": []
72 | },
73 | {
74 | "cell_type": "code",
75 | "execution_count": null,
76 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
77 | "metadata": {},
78 | "outputs": [],
79 | "source": []
80 | }
81 | ],
82 | "metadata": {
83 | "kernelspec": {
84 | "display_name": "Python 3 (ipykernel)",
85 | "language": "python",
86 | "name": "python3"
87 | },
88 | "language_info": {
89 | "codemirror_mode": {
90 | "name": "ipython",
91 | "version": 3
92 | },
93 | "file_extension": ".py",
94 | "mimetype": "text/x-python",
95 | "name": "python",
96 | "nbconvert_exporter": "python",
97 | "pygments_lexer": "ipython3",
98 | "version": "3.12.7"
99 | }
100 | },
101 | "nbformat": 4,
102 | "nbformat_minor": 5
103 | }
104 |
--------------------------------------------------------------------------------
/Book3_Ch04_Python_Codes/Bk3_Ch04_09.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 04\n",
9 | "\n",
10 | "# 求根\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "31cdebe4-0b0d-42dc-a9ea-f4b908459cea",
17 | "metadata": {},
18 | "source": [
19 | "该代码利用`sympy`和`numpy`库分别求解多项式方程$$-x^3 + x = 0$$的根。首先,`sympy`库使用符号运算求解此方程。将方程因式分解为$$x(x^2 - 1) = 0$$,得到三个根:\n",
20 | "\n",
21 | "$$\n",
22 | "x = 0, \\quad x = 1, \\quad x = -1\n",
23 | "$$\n",
24 | "\n",
25 | "接着,代码使用`numpy`中的`roots`函数来计算方程的数值解。通过提供系数列表`[-1, 0, 1, 0]`(对应于方程的项$-x^3 + x$),`numpy`计算出该方程的根,得到相同的结果。\n",
26 | "\n",
27 | "这种方法的优势在于同时展示了符号解与数值解的不同计算方式:`sympy`适合精确解法,而`numpy`则高效处理数值计算。两者结合可有效应对多项式方程的多种求解需求。"
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "id": "e8d7941d-f4f5-40bb-a686-1e1caed40945",
33 | "metadata": {},
34 | "source": [
35 | "## 使用 sympy 求解方程"
36 | ]
37 | },
38 | {
39 | "cell_type": "code",
40 | "execution_count": 1,
41 | "id": "706d62df-e328-4a98-8927-ef588361c735",
42 | "metadata": {},
43 | "outputs": [
44 | {
45 | "data": {
46 | "text/plain": [
47 | "[-1, 0, 1]"
48 | ]
49 | },
50 | "execution_count": 1,
51 | "metadata": {},
52 | "output_type": "execute_result"
53 | }
54 | ],
55 | "source": [
56 | "from sympy.solvers import solve\n",
57 | "from sympy import Symbol\n",
58 | "\n",
59 | "x = Symbol('x') # 定义符号x\n",
60 | "\n",
61 | "roots = solve(-x**3 + x, x) # 求解方程 -x^3 + x = 0\n",
62 | "roots # 输出方程的根"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "id": "a7249b8d-18bf-443a-927c-61ae269f9179",
68 | "metadata": {},
69 | "source": [
70 | "## 使用 numpy 求解方程"
71 | ]
72 | },
73 | {
74 | "cell_type": "code",
75 | "execution_count": 2,
76 | "id": "ee053c88-bb21-4e5d-8c39-d21a738588ee",
77 | "metadata": {},
78 | "outputs": [
79 | {
80 | "data": {
81 | "text/plain": [
82 | "array([ 1., -1., 0.])"
83 | ]
84 | },
85 | "execution_count": 2,
86 | "metadata": {},
87 | "output_type": "execute_result"
88 | }
89 | ],
90 | "source": [
91 | "import numpy as np\n",
92 | "\n",
93 | "coeff = [-1, 0, 1, 0] # 定义方程的系数\n",
94 | "\n",
95 | "roots_V2 = np.roots(coeff) # 使用 numpy 求解多项式的根\n",
96 | "roots_V2 # 输出方程的根"
97 | ]
98 | },
99 | {
100 | "cell_type": "code",
101 | "execution_count": null,
102 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
103 | "metadata": {},
104 | "outputs": [],
105 | "source": []
106 | },
107 | {
108 | "cell_type": "code",
109 | "execution_count": null,
110 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
111 | "metadata": {},
112 | "outputs": [],
113 | "source": []
114 | }
115 | ],
116 | "metadata": {
117 | "kernelspec": {
118 | "display_name": "Python 3 (ipykernel)",
119 | "language": "python",
120 | "name": "python3"
121 | },
122 | "language_info": {
123 | "codemirror_mode": {
124 | "name": "ipython",
125 | "version": 3
126 | },
127 | "file_extension": ".py",
128 | "mimetype": "text/x-python",
129 | "name": "python",
130 | "nbconvert_exporter": "python",
131 | "pygments_lexer": "ipython3",
132 | "version": "3.12.7"
133 | }
134 | },
135 | "nbformat": 4,
136 | "nbformat_minor": 5
137 | }
138 |
--------------------------------------------------------------------------------
/Book3_Ch04_Python_Codes/Streamlit_Bk3_Ch04_05.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | # 导入所需的库
9 | from sympy.abc import x # 引入符号 x,用于定义多项式变量
10 | from sympy import Poly, latex # 用于处理多项式及生成 LaTeX 表达式
11 | import matplotlib.pyplot as plt # 用于绘制图形
12 | import numpy as np # 用于数值计算
13 | import streamlit as st # 用于创建交互式应用
14 |
15 | ## 创建交互式滑块,用于用户输入多项式的阶数
16 | with st.sidebar:
17 |
18 | # 添加一个滑块,让用户选择多项式的阶数 n
19 | n = st.slider('Degree of a polynomial: ', # 滑块的描述
20 | min_value=2, # 最小值
21 | max_value=20, # 最大值
22 | value=10, # 默认值
23 | step=1) # 步长
24 |
25 | ## 定义多项式表达式
26 | expr = (x + 1)**n # 定义多项式表达式 (x + 1)^n
27 |
28 | # 在界面上显示多项式的公式
29 | st.latex(expr)
30 |
31 | # 展开多项式表达式
32 | expr_expand = expr.expand() # 使用 SymPy 的 expand 函数展开多项式
33 | expr_expand = Poly(expr_expand) # 将多项式转换为 Poly 对象
34 |
35 | # 在界面上以 LaTeX 格式显示展开后的多项式
36 | st.latex(latex(expr.expand()))
37 |
38 | # 获取多项式的系数
39 | poly_coeffs = expr_expand.coeffs() # 获取多项式的所有系数
40 |
41 | # 定义多项式各项的次数
42 | degrees = np.linspace(n, 0, n + 1) # 生成从 n 到 0 的等间隔值,表示每项的次数
43 |
44 | ## 绘制系数柱状图
45 | fig, ax = plt.subplots() # 创建图形和坐标轴
46 | ## 设置背景透明
47 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
48 | ax.set_facecolor('none') # 设置坐标轴背景为透明
49 | # 使用 stem 图绘制多项式系数
50 | plt.stem(degrees, np.array(poly_coeffs, dtype=float), basefmt=" ") # 绘制系数图
51 |
52 | # 设置 x 轴范围
53 | plt.xlim(0, n) # x 轴范围从 0 到 n
54 | plt.xticks(np.arange(0, n + 1)) # 设置 x 轴刻度为 0 到 n
55 |
56 | # 设置 y 轴范围
57 | y_max = max(poly_coeffs) # 获取系数的最大值
58 | y_max = float(y_max) # 转换为浮点数
59 | plt.ylim(0, y_max * 1.05) # 设置 y 轴范围为 [0, 最大值的 105%]
60 |
61 | # 隐藏右侧和顶部的边框
62 | ax.spines['right'].set_visible(False) # 隐藏右侧边框
63 | ax.spines['top'].set_visible(False) # 隐藏顶部边框
64 |
65 | # 反转 x 轴,使次数从高到低排列
66 | ax.invert_xaxis() # 反转 x 轴
67 |
68 | # 设置坐标轴标签
69 | plt.xlabel('Degree') # 设置 x 轴标签
70 | plt.ylabel('Coefficient') # 设置 y 轴标签
71 |
72 | ## 在 Streamlit 中显示图形
73 | st.pyplot(fig) # 使用 Streamlit 显示图形
74 |
--------------------------------------------------------------------------------
/Book3_Ch04_代数__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch04_代数__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch05_Python_Codes/Streamlit_Bk3_Ch05_03.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | # 导入必要的库
9 | import numpy as np # 用于数值计算
10 | import matplotlib.pyplot as plt # 用于绘制图形
11 | import streamlit as st # 用于创建交互式Web应用
12 |
13 | ## 创建交互式输入界面
14 | with st.sidebar: # 在侧边栏添加滑块和公式显示
15 |
16 | # 显示线性函数公式
17 | st.latex('y = ax + b')
18 |
19 | # 创建滑块以控制斜率 a,范围为-4到4,步长为0.1
20 | a = st.slider('Slope, a:',
21 | min_value=-4.0,
22 | max_value=4.0,
23 | step=0.1)
24 |
25 | # 创建滑块以控制截距 b,范围为-4到4,步长为0.1
26 | b = st.slider('Intercept, b:',
27 | min_value=-4.0,
28 | max_value=4.0,
29 | step=0.1)
30 |
31 | ## 显示当前线性函数公式
32 | st.latex("y = %.2f x + %.2f" % (a, b)) # 格式化显示公式
33 |
34 | ## 设置图形的全局样式
35 | plt.rcParams["figure.figsize"] = [7.50, 3.50] # 设置图形尺寸
36 | plt.rcParams["figure.autolayout"] = True # 自动调整图形布局
37 |
38 | ## 定义x和y的数据范围
39 | x_array = np.arange(-10, 10 + 1, step=1) # 定义x的取值范围为-10到10
40 | y_array = a * x_array + b # 根据公式计算y值
41 |
42 | ## 创建图形和坐标轴
43 | fig, ax = plt.subplots()
44 | ## 设置背景透明
45 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
46 | ax.set_facecolor('none') # 设置坐标轴背景为透明
47 | # 绘制线性函数的图像
48 | plt.plot(x_array, y_array, color='#00448A', linewidth=1.5)
49 |
50 | # 添加坐标轴标签
51 | plt.xlabel('$x_1$') # 设置x轴标签
52 | plt.ylabel('$x_2$ ') # 设置y轴标签
53 |
54 | # 添加x轴和y轴的零线
55 | plt.axhline(y=0, color='0.5', linestyle='-') # 添加y轴的零线
56 | plt.axvline(x=0, color='0.5', linestyle='-') # 添加x轴的零线
57 |
58 | # 设置主刻度和次刻度
59 | plt.xticks(np.arange(-10, 10 + 1, step=2)) # 设置主刻度
60 | plt.yticks(np.arange(-10, 10 + 1, step=2)) # 设置主刻度
61 | plt.axis('scaled') # 确保坐标轴的比例一致
62 | plt.minorticks_on() # 开启次刻度
63 |
64 | # 配置网格样式
65 | ax.grid(which='major', linestyle=':',
66 | linewidth='0.5', color=[0.8, 0.8, 0.8]) # 主网格样式
67 | ax.grid(linestyle='--', linewidth=0.25, color=[0.5, 0.5, 0.5]) # 次网格样式
68 |
69 | # 设置坐标轴范围
70 | ax.set_xlim(-10, 10) # 设置x轴范围
71 | ax.set_ylim(-10, 10) # 设置y轴范围
72 |
73 | # 隐藏图形的边框
74 | ax.spines['top'].set_visible(False) # 隐藏顶部边框
75 | ax.spines['right'].set_visible(False) # 隐藏右侧边框
76 | ax.spines['bottom'].set_visible(False) # 隐藏底部边框
77 | ax.spines['left'].set_visible(False) # 隐藏左侧边框
78 |
79 | ## 在Streamlit中显示图形
80 | st.pyplot(fig) # 使用Streamlit显示图形
81 |
--------------------------------------------------------------------------------
/Book3_Ch05_笛卡尔坐标系__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch05_笛卡尔坐标系__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch06_Python_Codes/Streamlit_Bk3_Ch6_01.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | # 导入必要的库
9 | import streamlit as st # 用于创建交互式应用
10 | import numpy as np # 用于数值计算
11 | from sympy import latex, symbols # 用于符号处理和公式显示
12 | import plotly.graph_objects as go # 用于3D绘图和等高线图
13 |
14 | ## 创建交互式输入界面
15 | with st.sidebar: # 在侧边栏添加滑块和公式显示
16 |
17 | # 显示公式
18 | st.latex('y = f(x_1, x_2) = ax_1 + bx_2 + c')
19 |
20 | # 定义参数a的滑块,范围为-2到2,步长为0.1
21 | a = st.slider('a: ',
22 | min_value=-2.0,
23 | max_value=2.0,
24 | step=0.1)
25 |
26 | # 定义参数b的滑块,范围为-2到2,步长为0.1
27 | b = st.slider('b: ',
28 | min_value=-2.0,
29 | max_value=2.0,
30 | step=0.1)
31 |
32 | # 定义参数c的滑块,范围为-2到2,步长为0.1
33 | c = st.slider('c: ',
34 | min_value=-2.0,
35 | max_value=2.0,
36 | step=0.1)
37 |
38 | ## 定义公式和计算网格值
39 | x1, x2 = symbols('x1 x2') # 定义符号变量 x1 和 x2
40 | y = a * x1 + b * x2 + c # 定义线性函数公式
41 |
42 | # 生成计算网格
43 | num = 33 # 定义网格点数量
44 | x1_array = np.linspace(-4, 4, num) # 生成 x1 的线性等分点
45 | x2_array = np.linspace(-4, 4, num) # 生成 x2 的线性等分点
46 | xx1, xx2 = np.meshgrid(x1_array, x2_array) # 生成二维网格
47 |
48 | # 显示公式的 LaTeX 形式
49 | st.latex('f(x_1, x_2) = ' + latex(y))
50 |
51 | # 计算网格上函数的值
52 | yy = a * xx1 + b * xx2 + c
53 |
54 | ## 绘制3D曲面图
55 | fig_1 = go.Figure(go.Surface(
56 | x=x1_array, # 设置 x 轴数据
57 | y=x2_array, # 设置 y 轴数据
58 | z=yy # 设置 z 轴数据(函数值)
59 | ))
60 |
61 | # 设置图形的布局和大小
62 | fig_1.update_layout(
63 | autosize=False,
64 | width=800, # 图形宽度
65 | height=800 # 图形高度
66 | )
67 |
68 | # 在 Streamlit 应用中显示 3D 曲面图
69 | st.plotly_chart(fig_1)
70 |
71 | ## 绘制等高线图
72 | fig_2 = go.Figure(data=go.Contour(
73 | x=x1_array, # 设置 x 轴数据
74 | y=x2_array, # 设置 y 轴数据
75 | z=yy # 设置 z 轴数据(函数值)
76 | ))
77 |
78 | # 设置图形的布局和大小
79 | fig_2.update_layout(
80 | autosize=False,
81 | width=800, # 图形宽度
82 | height=800 # 图形高度
83 | )
84 |
85 | # 在 Streamlit 应用中显示等高线图
86 | st.plotly_chart(fig_2)
87 |
--------------------------------------------------------------------------------
/Book3_Ch06_三维坐标系__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch06_三维坐标系__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch07_Python_Codes/Streamlit_Bk3_Ch07_06.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | # 导入必要的库
9 | import numpy as np # 导入NumPy库,用于数值计算
10 | from sympy import lambdify, sqrt # 从SymPy库中导入函数求值和平方根计算
11 | from sympy.abc import x, y # 定义符号变量x和y
12 | import matplotlib.pyplot as plt # 导入Matplotlib库,用于绘图
13 | import streamlit as st # 导入Streamlit库,用于创建交互式应用
14 |
15 | ## 定义绘制函数,用于绘制点、等距线和关系曲线
16 | def plot_fcn(A, B, dist_AX_zz, dist_BX_zz, distance):
17 | fig, ax = plt.subplots() # 创建绘图窗口
18 | ## 设置背景透明
19 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
20 | ax.set_facecolor('none') # 设置坐标轴背景为透明
21 | plt.plot(A[0], A[1], color='k', marker='x', markersize=12) # 绘制点A的位置
22 | colorbar = ax.contour(xx, yy, dist_AX_zz, levels=np.arange(0, 15 + 1), cmap='RdYlBu_r') # 绘制以A为中心的等距线
23 |
24 | plt.plot(B[0], B[1], color='k', marker='x', markersize=12) # 绘制点B的位置
25 | colorbar = ax.contour(xx, yy, dist_BX_zz, levels=np.arange(0, 15 + 1), cmap='RdYlBu_r') # 绘制以B为中心的等距线
26 |
27 | ax.contour(xx, yy, distance, levels=0, colors='0.5') # 绘制关系曲线
28 |
29 | fig.colorbar(colorbar, ax=ax) # 添加颜色条
30 | plt.xlabel('x') # 设置x轴标签
31 | plt.ylabel('y') # 设置y轴标签
32 | plt.axhline(y=0, color='0.8', linestyle='-') # 绘制x轴
33 | plt.axvline(x=0, color='0.8', linestyle='-') # 绘制y轴
34 | plt.xticks(np.arange(-10, 10, step=2)) # 设置x轴刻度
35 | plt.yticks(np.arange(-10, 10, step=2)) # 设置y轴刻度
36 | plt.axis('scaled') # 设置坐标轴比例相等
37 |
38 | ax.set_xlim(x_array.min(), x_array.max()) # 设置x轴范围
39 | ax.set_ylim(y_array.min(), y_array.max()) # 设置y轴范围
40 | ax.spines['top'].set_visible(False) # 隐藏顶部边框
41 | ax.spines['right'].set_visible(False) # 隐藏右侧边框
42 | ax.spines['bottom'].set_visible(False) # 隐藏底部边框
43 | ax.spines['left'].set_visible(False) # 隐藏左侧边框
44 |
45 | ax.grid(linestyle='--', linewidth=0.25, color=[0.8, 0.8, 0.8]) # 添加网格线
46 |
47 | return fig # 返回绘图对象
48 |
49 | ## 设置交互界面的选项
50 | options = (
51 | 'AP - BP = 0',
52 | 'AP - BP - 3 = 0',
53 | 'AP - BP + 3 = 0',
54 | 'AP - 2*BP = 0',
55 | 'BP + AP - 8 = 0'
56 | )
57 |
58 | with st.sidebar: # 在侧边栏设置用户交互输入
59 | option_i = st.selectbox('Choose a relation:', options) # 用户选择关系表达式
60 | A_x = st.slider('x coordinate of A:', min_value=2.0, max_value=4.0, step=0.1) # 点A的x坐标
61 | A_y = st.slider('y coordinate of A:', min_value=2.0, max_value=4.0, step=0.1) # 点A的y坐标
62 | B_x = st.slider('x coordinate of B:', min_value=0.0, max_value=2.0, step=0.1) # 点B的x坐标
63 | B_y = st.slider('y coordinate of B:', min_value=-2.0, max_value=-4.0, step=0.1) # 点B的y坐标
64 |
65 | ## 定义点A和点B的坐标
66 | A = [A_x, A_y]
67 | B = [B_x, B_y]
68 |
69 | st.latex('A = ' + str(A)) # 显示点A的坐标
70 | st.latex('B = ' + str(B)) # 显示点B的坐标
71 |
72 | ## 生成网格
73 | num = 301 # 定义网格数量
74 | x_array = np.linspace(-8, 8, num) # 定义x方向的网格范围
75 | y_array = np.linspace(-8, 8, num) # 定义y方向的网格范围
76 | xx, yy = np.meshgrid(x_array, y_array) # 创建二维网格
77 |
78 | ## 定义点A和点B到任意点P的距离函数
79 | dist_AX = sqrt((x - A[0])**2 + (y - A[1])**2) # 点A到点P的距离
80 | dist_BX = sqrt((x - B[0])**2 + (y - B[1])**2) # 点B到点P的距离
81 |
82 | dist_AX_fcn = lambdify([x, y], dist_AX) # 将点A的距离函数转换为可计算形式
83 | dist_BX_fcn = lambdify([x, y], dist_BX) # 将点B的距离函数转换为可计算形式
84 |
85 | dist_AX_zz = dist_AX_fcn(xx, yy) # 计算点A到网格上每个点的距离
86 | dist_BX_zz = dist_BX_fcn(xx, yy) # 计算点B到网格上每个点的距离
87 |
88 | ## 根据用户选择的关系表达式绘制结果
89 | if option_i == 'AP - BP = 0':
90 | st.latex('AP - BP = 0') # 显示选择的关系
91 | distance = dist_AX_zz - dist_BX_zz # 计算关系曲线
92 | fig = plot_fcn(A, B, dist_AX_zz, dist_BX_zz, distance) # 绘制图形
93 | st.pyplot(fig) # 显示图形
94 |
95 | elif option_i == 'AP - BP - 3 = 0':
96 | st.latex('AP - BP - 3 = 0')
97 | distance = dist_AX_zz - dist_BX_zz - 3
98 | fig = plot_fcn(A, B, dist_AX_zz, dist_BX_zz, distance)
99 | st.pyplot(fig)
100 |
101 | elif option_i == 'AP - BP + 3 = 0':
102 | st.latex('AP - BP + 3 = 0')
103 | distance = dist_AX_zz - dist_BX_zz + 3
104 | fig = plot_fcn(A, B, dist_AX_zz, dist_BX_zz, distance)
105 | st.pyplot(fig)
106 |
107 | elif option_i == 'AP - 2*BP = 0':
108 | st.latex('AP - 2*BP = 0')
109 | distance = dist_AX_zz - 2 * dist_BX_zz
110 | fig = plot_fcn(A, B, dist_AX_zz, dist_BX_zz, distance)
111 | st.pyplot(fig)
112 |
113 | elif option_i == 'BP + AP - 8 = 0':
114 | st.latex('BP + AP - 8 = 0')
115 | distance = dist_BX_zz + dist_AX_zz - 8
116 | fig = plot_fcn(A, B, dist_AX_zz, dist_BX_zz, distance)
117 | st.pyplot(fig)
118 |
--------------------------------------------------------------------------------
/Book3_Ch07_距离__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch07_距离__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch08_圆锥曲线__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch08_圆锥曲线__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch09_Python_Codes/Streamlit_Bk3_Ch09_03.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | # 导入必要的库
9 | import streamlit as st # 导入Streamlit库,用于创建交互式Web应用
10 | import matplotlib.pyplot as plt # 导入Matplotlib库,用于绘图
11 | import numpy as np # 导入NumPy库,用于数值计算
12 | import matplotlib.patches as patches # 导入Matplotlib的补丁模块,用于添加矩形
13 |
14 | # 设置标题
15 | st.header('Chapter 9, Dive into Conic Sections | Book 3') # 在Streamlit页面上显示标题
16 |
17 | ## 设置侧边栏输入参数
18 | with st.sidebar:
19 | # 定义m的滑动条
20 | m = st.slider('Define m: ', 1.0, 2.0, value=1.5, step=0.1)
21 | st.write('m is ' + str(m)) # 在侧边栏显示当前m的值
22 |
23 | # 定义n的滑动条
24 | n = st.slider('Define n: ', 1.0, 2.0, value=1.5, step=0.1)
25 | st.write('n is ' + str(n)) # 在侧边栏显示当前n的值
26 |
27 | # 定义rho的滑动条
28 | rho = st.slider('Define rho: ', -1.0, 1.0, value=0.0, step=0.05)
29 | st.write('rho is ' + str(rho)) # 在侧边栏显示当前rho的值
30 |
31 | ## 主绘图部分
32 |
33 | # 定义网格范围和分辨率
34 | x = np.linspace(-4, 4, num=201) # x轴的值,从-4到4,分成201个点
35 | y = np.linspace(-4, 4, num=201) # y轴的值,从-4到4,分成201个点
36 | xx, yy = np.meshgrid(x, y) # 生成二维网格
37 |
38 | # 创建一个绘图窗口
39 | fig, ax = plt.subplots(figsize=(8, 8)) # 设置绘图窗口大小
40 |
41 | # 添加矩形,用于表示椭圆的外接矩形
42 | rect = patches.Rectangle(
43 | (-m, -n), # 矩形左下角坐标
44 | 2 * m, # 矩形的宽度
45 | 2 * n, # 矩形的高度
46 | linewidth=0.25, # 矩形边框的线宽
47 | edgecolor='0.6', # 矩形边框的颜色
48 | linestyle='--', # 矩形边框的线型
49 | facecolor='none' # 矩形的填充颜色为空
50 | )
51 | ax.add_patch(rect) # 将矩形添加到绘图窗口中
52 |
53 | # 定义椭圆方程
54 | ellipse = ((xx / m)**2 - 2 * rho * (xx / m) * (yy / n) + (yy / n)**2) / (1 - rho**2)
55 |
56 | # 绘制椭圆的等高线
57 | plt.contour(xx, yy, ellipse, levels=[1], colors=['b']) # 绘制椭圆的轮廓线
58 |
59 | # 绘制椭圆的四个顶点
60 | plt.plot(m, rho * n, 'x', color='r', markersize=12) # 顶点1
61 | plt.plot(rho * m, n, 'x', color='r', markersize=12) # 顶点2
62 | plt.plot(-m, -rho * n, 'x', color='r', markersize=12) # 顶点3
63 | plt.plot(-rho * m, -n, 'x', color='r', markersize=12) # 顶点4
64 |
65 | # 绘制坐标轴
66 | plt.axvline(x=0, color='0.6', linestyle='-') # y轴
67 | plt.axhline(y=0, color='0.6', linestyle='-') # x轴
68 |
69 | # 设置绘图窗口的坐标轴属性
70 | ax.set_xticks([]) # 隐藏x轴刻度
71 | ax.set_yticks([]) # 隐藏y轴刻度
72 | ax.set_xlim([-2, 2]) # 设置x轴显示范围
73 | ax.set_ylim([-2, 2]) # 设置y轴显示范围
74 |
75 | # 隐藏绘图窗口的边框
76 | ax.spines['top'].set_visible(False) # 隐藏顶部边框
77 | ax.spines['right'].set_visible(False) # 隐藏右侧边框
78 | ax.spines['bottom'].set_visible(False) # 隐藏底部边框
79 | ax.spines['left'].set_visible(False) # 隐藏左侧边框
80 | ## 设置背景透明
81 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
82 | ax.set_facecolor('none') # 设置坐标轴背景为透明
83 | # 在Streamlit界面显示绘图
84 | st.pyplot(fig) # 将绘图结果嵌入到Streamlit的Web界面中
85 |
--------------------------------------------------------------------------------
/Book3_Ch09_Python_Codes/Streamlit_Bk3_Ch09_04.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | # 导入必要的库
9 | import matplotlib.pyplot as plt # 导入Matplotlib库,用于绘制图形
10 | import numpy as np # 导入NumPy库,用于数值计算
11 | import streamlit as st # 导入Streamlit库,用于创建交互式Web应用
12 |
13 | ## 设置侧边栏参数
14 | with st.sidebar:
15 | # 显示公式
16 | st.latex(r' \left|\frac{x_1}{a}\right|^p + \left|\frac{x_2}{b}\right|^q = 1')
17 |
18 | # 定义参数a的滑动条
19 | a = st.slider('a', min_value=1.0, max_value=3.0, step=0.1)
20 |
21 | # 定义参数b的滑动条
22 | b = st.slider('b', min_value=1.0, max_value=3.0, step=0.1)
23 |
24 | # 定义参数p的滑动条
25 | p = st.slider('p', min_value=0.2, max_value=3.0, step=0.1)
26 |
27 | # 定义参数q的滑动条
28 | q = st.slider('q', min_value=0.2, max_value=3.0, step=0.1)
29 |
30 | ## 在主界面显示当前的Lp规范公式
31 | st.latex(r' \left|\frac{x_1}{%.2f}\right|^{%.2f}+ \left|\frac{x_2}{%.2f}\right|^{%.2f} = 1'
32 | % (a, p, b, q))
33 |
34 | ## 定义网格
35 | x1 = np.linspace(-2, 2, num=101) # 定义x1的取值范围
36 | x2 = x1 # x2的取值范围与x1相同
37 | xx1, xx2 = np.meshgrid(x1, x2) # 创建二维网格
38 |
39 | ## 创建绘图窗口
40 | fig, ax = plt.subplots(figsize=(12, 12)) # 设置绘图窗口大小
41 |
42 | ## 设置背景透明
43 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
44 | ax.set_facecolor('none') # 设置坐标轴背景为透明
45 |
46 | ## 计算Lp规范的值
47 | if np.isinf(p): # 如果p的值趋近于无穷
48 | zz = np.maximum(np.abs(xx1 / a), np.abs(xx2 / b)) # L∞规范
49 | else:
50 | zz = ((np.abs(xx1 / a)**p) + (np.abs(xx2 / b)**q))**(1. / q) # Lp规范
51 |
52 | ## 绘制等高线图
53 | # 绘制Lp规范的等高线填充
54 | ax.contourf(xx1, xx2, zz, 20, cmap='RdYlBu_r')
55 |
56 | # 绘制Lp = 1的轮廓线
57 | ax.contour(xx1, xx2, zz, [1], colors='k', linewidths=2)
58 |
59 | ## 添加装饰和坐标轴设置
60 | ax.axhline(y=0, color='k', linewidth=0.25) # 添加x轴
61 | ax.axvline(x=0, color='k', linewidth=0.25) # 添加y轴
62 | ax.set_xlim(-2, 2) # 设置x轴范围
63 | ax.set_ylim(-2, 2) # 设置y轴范围
64 | ax.spines['top'].set_visible(False) # 隐藏顶部边框
65 | ax.spines['right'].set_visible(False) # 隐藏右侧边框
66 | ax.spines['bottom'].set_visible(False) # 隐藏底部边框
67 | ax.spines['left'].set_visible(False) # 隐藏左侧边框
68 | ax.set_xlabel('$x_1$') # 设置x轴标签
69 | ax.set_ylabel('$x_2$') # 设置y轴标签
70 | ax.set_aspect('equal', adjustable='box') # 设置坐标轴比例相等
71 |
72 | ## 在Streamlit界面显示绘图
73 | st.pyplot(fig) # 将绘图结果嵌入到Streamlit界面中
74 |
--------------------------------------------------------------------------------
/Book3_Ch09_深入圆锥曲线__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch09_深入圆锥曲线__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch10_Python_Codes/Bk3_Ch10_01.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 10\n",
9 | "\n",
10 | "# 函数单调性\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "0b761300-b5a8-4b68-8b40-002f8e2f5089",
17 | "metadata": {},
18 | "source": [
19 | "这段代码使用SymPy库来判断两个不同表达式在指定区间内的增减性。代码的核心是使用`is_increasing`函数分析每个表达式在给定区间上是否是单调递增的。\n",
20 | "\n",
21 | "1. **表达式1**:$$-x^2$$\n",
22 | " - 该表达式在区间$(-\\infty, 0)$上是单调递增的,因为随着$x$从负无穷趋近于0,$-x^2$的值在不断增加。而在区间$(0, \\infty)$上,该表达式是单调递减的,因为$x$的增大会导致$-x^2$值减少。\n",
23 | "\n",
24 | "2. **表达式2**:$$-x^2 + y$$\n",
25 | " - 在此表达式中,$y$是一个常数项,仅$x$是变量。代码判断其在区间$(-1, 2)$上对变量$x$的增减性。由于$-x^2$是一个开口向下的抛物线,因此表达式在区间$(-1, 2)$上不会是单调递增的。\n",
26 | "\n",
27 | "代码输出每个表达式在不同区间内的增减性,为分析表达式的单调性提供了定量依据。"
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "id": "59898e64-7527-4481-a74b-7125abf795cd",
33 | "metadata": {},
34 | "source": [
35 | "## 导入所需库"
36 | ]
37 | },
38 | {
39 | "cell_type": "code",
40 | "execution_count": 1,
41 | "id": "cd84786c-759e-4849-8570-6fb45993f3eb",
42 | "metadata": {},
43 | "outputs": [],
44 | "source": [
45 | "from sympy import is_increasing # 导入is_increasing函数用于判断表达式的增减性\n",
46 | "from sympy.abc import x, y # 定义符号变量x和y\n",
47 | "from sympy import Interval, oo # 导入Interval用于区间定义,oo表示无穷大"
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "id": "afd830cc-0c47-40d8-bf99-2b219a5272ef",
53 | "metadata": {},
54 | "source": [
55 | "## 定义表达式1并判断其增减性"
56 | ]
57 | },
58 | {
59 | "cell_type": "code",
60 | "execution_count": 2,
61 | "id": "34636bb4-1dbd-4da0-b067-d9934198a7e1",
62 | "metadata": {},
63 | "outputs": [
64 | {
65 | "data": {
66 | "text/latex": [
67 | "$\\displaystyle - x^{2}$"
68 | ],
69 | "text/plain": [
70 | "-x**2"
71 | ]
72 | },
73 | "execution_count": 2,
74 | "metadata": {},
75 | "output_type": "execute_result"
76 | }
77 | ],
78 | "source": [
79 | "expr_1 = -x**2 # 定义表达式1\n",
80 | "expr_1 # 输出表达式1"
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": 3,
86 | "id": "67d74dc7-4c74-4b6d-81ef-af2cea319865",
87 | "metadata": {},
88 | "outputs": [
89 | {
90 | "name": "stdout",
91 | "output_type": "stream",
92 | "text": [
93 | "True\n",
94 | "False\n"
95 | ]
96 | }
97 | ],
98 | "source": [
99 | "print(is_increasing(expr_1, Interval(-oo, 0))) # 判断表达式1在区间(-∞, 0)上的增减性\n",
100 | "print(is_increasing(expr_1, Interval(0, oo))) # 判断表达式1在区间(0, ∞)上的增减性"
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "id": "c3ff0b2c-1f0f-47a9-9b8b-00505710714b",
106 | "metadata": {},
107 | "source": [
108 | "## 定义表达式2并判断其增减性"
109 | ]
110 | },
111 | {
112 | "cell_type": "code",
113 | "execution_count": 4,
114 | "id": "99ad464f-6df0-4fde-bc9e-e0b329e7b4fa",
115 | "metadata": {},
116 | "outputs": [
117 | {
118 | "data": {
119 | "text/latex": [
120 | "$\\displaystyle - x^{2} + y$"
121 | ],
122 | "text/plain": [
123 | "-x**2 + y"
124 | ]
125 | },
126 | "execution_count": 4,
127 | "metadata": {},
128 | "output_type": "execute_result"
129 | }
130 | ],
131 | "source": [
132 | "expr_2 = -x**2 + y # 定义表达式2\n",
133 | "expr_2 # 输出表达式2"
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "execution_count": 5,
139 | "id": "cffe6d73-17d5-4b25-b48f-7819f182e17f",
140 | "metadata": {},
141 | "outputs": [
142 | {
143 | "name": "stdout",
144 | "output_type": "stream",
145 | "text": [
146 | "False\n"
147 | ]
148 | }
149 | ],
150 | "source": [
151 | "print(is_increasing(expr_2, Interval(-1, 2), x)) # 判断表达式2在区间(-1, 2)上对变量x的增减性"
152 | ]
153 | }
154 | ],
155 | "metadata": {
156 | "kernelspec": {
157 | "display_name": "Python 3 (ipykernel)",
158 | "language": "python",
159 | "name": "python3"
160 | },
161 | "language_info": {
162 | "codemirror_mode": {
163 | "name": "ipython",
164 | "version": 3
165 | },
166 | "file_extension": ".py",
167 | "mimetype": "text/x-python",
168 | "name": "python",
169 | "nbconvert_exporter": "python",
170 | "pygments_lexer": "ipython3",
171 | "version": "3.12.7"
172 | }
173 | },
174 | "nbformat": 4,
175 | "nbformat_minor": 5
176 | }
177 |
--------------------------------------------------------------------------------
/Book3_Ch10_Python_Codes/Streamlit_Bk3_Ch10_02.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | # 导入必要的库
9 | import numpy as np # 导入numpy库,用于数值计算
10 | from sympy import lambdify, exp, latex, symbols # 导入sympy库,用于符号数学
11 | import plotly.graph_objects as go # 导入plotly的图形对象模块,用于绘制3D和等高线图
12 | import streamlit as st # 导入streamlit库,用于创建交互式Web应用
13 |
14 | # 定义符号变量
15 | x1, x2 = symbols('x1 x2') # 定义两个符号变量x1和x2
16 |
17 | # 定义网格参数
18 | num = 301 # 网格点的数量
19 | x1_array = np.linspace(-3, 3, num) # 定义x1的取值范围,从-3到3
20 | x2_array = np.linspace(-3, 3, num) # 定义x2的取值范围,从-3到3
21 | xx1, xx2 = np.meshgrid(x1_array, x2_array) # 生成网格数据
22 |
23 | # 定义目标函数f(x1, x2)
24 | f_x = (3 * (1 - x1)**2 * exp(-(x1**2) - (x2 + 1)**2) # 第一项
25 | - 10 * (x1 / 5 - x1**3 - x2**5) * exp(-x1**2 - x2**2) # 第二项
26 | - 1 / 3 * exp(-(x1 + 1)**2 - x2**2)) # 第三项
27 |
28 | # 将符号函数转换为数值计算函数
29 | f_x_fcn = lambdify([x1, x2], f_x) # 使用lambdify将符号函数转换为Python函数
30 | f_zz = f_x_fcn(xx1, xx2) # 计算目标函数在网格点上的值
31 |
32 | # 在Streamlit中显示目标函数的LaTeX公式
33 | st.latex('f(x_1, x_2) = ' + latex(f_x)) # 使用LaTeX格式显示函数公式
34 |
35 | # ## 可视化部分
36 | # ### 3D曲面图
37 | fig_surface = go.Figure(go.Surface(
38 | x=x1_array, # 设置x轴的取值
39 | y=x2_array, # 设置y轴的取值
40 | z=f_zz, # 设置z轴的取值,即函数值
41 | showscale=False, # 隐藏颜色条
42 | colorscale='RdYlBu_r' # 设置颜色映射为红黄蓝反转
43 | ))
44 | fig_surface.update_layout(
45 | autosize=True, # 自动调整图像大小
46 | width=800, # 设置图像宽度
47 | height=600 # 设置图像高度
48 | )
49 | st.plotly_chart(fig_surface) # 在Streamlit中显示3D曲面图
50 |
51 | # ### 等高线图
52 | fig_contour = go.Figure(data=go.Contour(
53 | z=f_zz, # 设置z值
54 | x=x1_array, # 设置x轴的取值
55 | y=x2_array, # 设置y轴的取值
56 | colorscale='RdYlBu_r' # 设置颜色映射为红黄蓝反转
57 | ))
58 | fig_contour.update_layout(
59 | autosize=True, # 自动调整图像大小
60 | width=600, # 设置图像宽度
61 | height=600 # 设置图像高度
62 | )
63 | st.plotly_chart(fig_contour) # 在Streamlit中显示等高线图
64 |
--------------------------------------------------------------------------------
/Book3_Ch10_函数__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch10_函数__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch11_Python_Codes/Streamlit_Bk3_Ch11_03.py:
--------------------------------------------------------------------------------
1 | import streamlit as st # 导入Streamlit库,用于创建Web应用
2 | import numpy as np # 导入numpy库,用于数值计算
3 | import plotly.graph_objects as go # 导入plotly的图形对象模块
4 |
5 | # 定义x的取值范围
6 | x = np.linspace(-2, 2, 100) # x轴从-2到2,分成100个点
7 |
8 | # 定义一次、二次、三次函数
9 | linear = x # 一次函数 f1(x) = x
10 | quadratic = x**2 # 二次函数 f2(x) = x^2
11 | cubic = x**3 # 三次函数 f3(x) = x^3
12 |
13 | # 定义绘图函数
14 | def plot_curve(x, y, title="Function Plot"):
15 | """
16 | 使用Plotly绘制曲线
17 | """
18 | fig = go.Figure() # 创建一个Plotly图形对象
19 | fig.add_trace(go.Scatter(x=x, y=y, mode='lines', name=title, line=dict(width=2))) # 添加曲线
20 |
21 | # 配置布局
22 | fig.update_layout(
23 | title=title,
24 | xaxis_title="x",
25 | yaxis_title="f(x)",
26 | xaxis=dict(showgrid=True, zeroline=True),
27 | yaxis=dict(showgrid=True, zeroline=True),
28 | template="plotly_white",
29 | legend=dict(x=0.02, y=0.98),
30 | )
31 | # 显示图形
32 | st.plotly_chart(fig)
33 |
34 | # Streamlit 应用布局
35 | st.title("单项式叠加函数展示") # 设置应用标题
36 | st.write("### 基本函数图像") # 设置小标题
37 |
38 | # 绘制一次、二次、三次函数图像
39 | st.write("**一次函数**: $f_1(x) = x$")
40 | plot_curve(x, linear, title="f1(x) = x")
41 |
42 | st.write("**二次函数**: $f_2(x) = x^2$")
43 | plot_curve(x, quadratic, title="f2(x) = x^2")
44 |
45 | st.write("**三次函数**: $f_3(x) = x^3$")
46 | plot_curve(x, cubic, title="f3(x) = x^3")
47 |
48 | # 用户交互选择
49 | st.write("### 叠加函数设置")
50 | st.write("请选择叠加系数 $a$, $b$, $c$ 对应的权重:")
51 |
52 | # 使用多选按钮获取用户选择
53 | selected_terms = st.multiselect(
54 | "选择要叠加的单项式:",
55 | ["一次函数 ($f_1(x) = x$)", "二次函数 ($f_2(x) = x^2$)", "三次函数 ($f_3(x) = x^3$)"],
56 | default=["一次函数 ($f_1(x) = x$)"]
57 | )
58 |
59 | # 定义初始系数
60 | a, b, c = 0, 0, 0
61 | if "一次函数 ($f_1(x) = x$)" in selected_terms:
62 | a = st.slider("设置 $a$ 的值:", -10.0, 10.0, 1.0, step=0.1)
63 | if "二次函数 ($f_2(x) = x^2$)" in selected_terms:
64 | b = st.slider("设置 $b$ 的值:", -10.0, 10.0, 1.0, step=0.1)
65 | if "三次函数 ($f_3(x) = x^3$)" in selected_terms:
66 | c = st.slider("设置 $c$ 的值:", -10.0, 10.0, 1.0, step=0.1)
67 |
68 | # 叠加函数计算
69 | combined_function = a * linear + b * quadratic + c * cubic
70 |
71 | # 显示叠加函数公式
72 | st.write("### 叠加函数公式")
73 | latex_formula = f"f(x) = {a:.2f} \\cdot x + {b:.2f} \\cdot x^2 + {c:.2f} \\cdot x^3"
74 | st.latex(latex_formula)
75 |
76 | # 绘制叠加函数图像
77 | st.write("### 叠加函数图像")
78 | plot_curve(x, combined_function, title="叠加函数 f(x)")
79 |
--------------------------------------------------------------------------------
/Book3_Ch11_代数函数__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch11_代数函数__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch12_Python_Codes/Streamlit_Bk3_Ch12_02.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | # 导入必要的库
9 | import matplotlib.pyplot as plt # 用于绘图
10 | import streamlit as st # 用于交互式展示
11 | import numpy as np # 用于数值计算
12 | from sympy.abc import x # 定义符号变量 x
13 | from sympy import exp, lambdify, latex # 用于符号表达式处理和转换
14 |
15 | ## 设置 Streamlit 侧边栏,用于用户输入参数
16 | with st.sidebar:
17 | st.latex(r'f(x) = a \exp(- (b(x - c))^2) + d') # 显示函数公式
18 | a = st.slider('a', min_value=-2.0, max_value=2.0, step=0.1) # 滑动条,设置参数 a
19 | b = st.slider('b', min_value=-2.0, max_value=2.0, step=0.1) # 滑动条,设置参数 b
20 | c = st.slider('c', min_value=-2.0, max_value=2.0, step=0.1) # 滑动条,设置参数 c
21 | d = st.slider('d', min_value=-2.0, max_value=2.0, step=0.1) # 滑动条,设置参数 d
22 |
23 | ## 定义函数 f(x)
24 | x_array = np.arange(-4, 4 + 0.01, step=0.01) # 在区间 [-4, 4] 内生成 x 的取值
25 | f_x = a * exp(-(b * (x - c))**2) + d # 定义目标函数
26 | st.latex('f(x) = ' + latex(f_x)) # 将符号表达式显示为 LaTeX 格式
27 |
28 | ## 将符号函数转换为数值函数
29 | f_x_fcn = lambdify([x], f_x) # 将符号表达式转换为 Python 函数
30 | f_x_array = f_x_fcn(x_array) # 计算目标函数的数值结果
31 |
32 | ## 绘制目标函数
33 | fig, ax = plt.subplots() # 创建绘图对象
34 | ## 设置背景透明
35 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
36 | ax.set_facecolor('none') # 设置坐标轴背景为透明
37 |
38 | plt.plot(x_array, f_x_array, color='#0070C0', label='f(x)') # 绘制函数曲线
39 | plt.xlabel('x') # 设置 x 轴标签
40 | plt.ylabel('y') # 设置 y 轴标签
41 | plt.axhline(y=0, color='k', linestyle='-') # 添加 y=0 的水平参考线
42 | plt.axvline(x=0, color='k', linestyle='-') # 添加 x=0 的垂直参考线
43 | plt.xticks(np.arange(-4, 4 + 1, step=1)) # 设置 x 轴刻度
44 | plt.yticks(np.arange(-4, 4 + 1, step=1)) # 设置 y 轴刻度
45 | plt.axis('scaled') # 设置坐标轴比例
46 |
47 | ## 设置图形样式
48 | ax.set_xlim(-4, 4) # 设置 x 轴范围
49 | ax.set_ylim(-4, 4) # 设置 y 轴范围
50 | ax.spines['top'].set_visible(False) # 隐藏顶部边框
51 | ax.spines['right'].set_visible(False) # 隐藏右侧边框
52 | ax.spines['bottom'].set_visible(False) # 隐藏底部边框
53 | ax.spines['left'].set_visible(False) # 隐藏左侧边框
54 |
55 | plt.legend() # 显示图例
56 | ax.grid(linestyle='--', linewidth=0.25, color=[0.5, 0.5, 0.5]) # 添加网格线
57 |
58 | ## 设置全局绘图参数
59 | plt.rcParams["figure.figsize"] = [7.50, 3.50] # 设置图形尺寸
60 | plt.rcParams["figure.autolayout"] = True # 自动布局调整
61 |
62 | st.pyplot(fig) # 在 Streamlit 中显示绘图
63 |
--------------------------------------------------------------------------------
/Book3_Ch12_超越函数__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch12_超越函数__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch13_Python_Codes/Streamlit_Bk3_Ch13_01.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | import math # 导入数学模块
9 | import numpy as np # 导入 numpy 模块,用于数值计算
10 | import matplotlib.pyplot as plt # 导入 matplotlib 模块,用于绘图
11 | from matplotlib import cm # 导入 matplotlib 的 colormap,用于颜色映射
12 | import streamlit as st # 导入 streamlit 模块,用于创建交互式界面
13 | from sympy import symbols, lambdify # 导入 sympy 模块,用于符号运算
14 | import plotly.graph_objects as go # 导入 plotly 的 graph_objects,用于交互式绘图
15 |
16 | ## 定义生成网格的函数
17 | def mesh_square(x1_0, x2_0, r, num):
18 | rr = np.linspace(-r, r, num) # 在指定范围生成均匀分布的点
19 | xx1, xx2 = np.meshgrid(rr, rr) # 创建二维网格
20 | xx1 = xx1 + x1_0 # 平移网格中心到 x1_0
21 | xx2 = xx2 + x2_0 # 平移网格中心到 x2_0
22 | return xx1, xx2, rr # 返回生成的网格和坐标数组
23 |
24 | ## 定义绘制 3D 曲面的函数
25 | def plot_surf(xx1, xx2, ff):
26 | norm_plt = plt.Normalize(ff.min(), ff.max()) # 归一化颜色映射范围
27 | colors = cm.coolwarm(norm_plt(ff)) # 使用 coolwarm 颜色映射
28 | fig = plt.figure() # 创建图形
29 | ax = fig.add_subplot(projection='3d') # 添加 3D 坐标轴
30 | surf = ax.plot_surface(xx1, xx2, ff, facecolors=colors, shade=False) # 绘制曲面
31 | surf.set_facecolor((0, 0, 0, 0)) # 设置背景为透明
32 | ax.set_xlabel('$\it{x_1}$') # 设置 x 轴标签
33 | ax.set_ylabel('$\it{x_2}$') # 设置 y 轴标签
34 | ax.set_zlabel('$\it{f}$($\it{x_1}$,$\it{x_2}$)') # 设置 z 轴标签
35 | return fig # 返回绘制的图形
36 |
37 | ## 定义绘制等高线的函数
38 | def plot_contourf(xx1, xx2, ff):
39 | fig, ax = plt.subplots() # 创建图形和坐标轴
40 | cntr2 = ax.contourf(xx1, xx2, ff, levels=15, cmap="RdBu_r") # 绘制填充等高线
41 | fig.colorbar(cntr2, ax=ax) # 添加颜色条
42 | ax.set_xlabel('$\it{x_1}$') # 设置 x 轴标签
43 | ax.set_ylabel('$\it{x_2}$') # 设置 y 轴标签
44 | ax.grid(linestyle='--', linewidth=0.25, color=[0.5, 0.5, 0.5]) # 设置网格样式
45 | return fig # 返回绘制的图形
46 |
47 | ## 设置 Streamlit 侧边栏交互控件
48 | with st.sidebar:
49 | st.latex(r'f(x_1,x_2) = ax_1^2 + bx_1x_2 + cx_2^2 + dx_1 + ex_2 + f') # 显示数学公式
50 | a = st.slider('a', min_value=-2.0, max_value=2.0, step=0.1) # 滑动条选择参数 a
51 | b = st.slider('b', min_value=-2.0, max_value=2.0, step=0.1) # 滑动条选择参数 b
52 | c = st.slider('c', min_value=-2.0, max_value=2.0, step=0.1) # 滑动条选择参数 c
53 | d = st.slider('d', min_value=-2.0, max_value=2.0, step=0.1) # 滑动条选择参数 d
54 | e = st.slider('e', min_value=-2.0, max_value=2.0, step=0.1) # 滑动条选择参数 e
55 | f = st.slider('f', min_value=-2.0, max_value=2.0, step=0.1) # 滑动条选择参数 f
56 |
57 | ## 初始化网格和符号表达式
58 | x1, x2 = symbols('x1 x2') # 定义符号变量
59 | x1_0, x2_0 = 0, 0 # 设置网格中心
60 | r, num = 2, 30 # 设置网格半径和点数
61 | xx1, xx2, x1_array = mesh_square(x1_0, x2_0, r, num) # 生成网格
62 | x2_array = x1_array # y 轴坐标与 x 轴一致
63 |
64 | ## 使用 matplotlib 可视化
65 | f_sym = a * x1**2 + b * x1 * x2 + c * x2**2 + d * x1 + e * x2 + f # 定义目标函数
66 | f_fcn = lambdify([x1, x2], f_sym) # 将符号函数转换为数值函数
67 | ff = f_fcn(xx1, xx2) # 计算目标函数值
68 | fig_1 = plot_surf(xx1, xx2, ff) # 绘制 3D 曲面
69 | fig_2 = plot_contourf(xx1, xx2, ff) # 绘制等高线
70 |
71 | ## 使用 Plotly 可视化
72 | fig_surface = go.Figure(go.Surface(
73 | x=x1_array, y=x2_array, z=ff, showscale=False, colorscale='RdYlBu_r')) # 绘制交互式 3D 曲面
74 | fig_surface.update_layout(autosize=True, width=800, height=600) # 设置布局大小
75 | st.plotly_chart(fig_surface) # 在 Streamlit 中显示 3D 曲面图
76 |
77 | fig_contour = go.Figure(data=go.Contour(
78 | z=ff, x=x1_array, y=x2_array, colorscale='RdYlBu_r')) # 绘制交互式等高线
79 | fig_contour.update_layout(autosize=True, width=600, height=600) # 设置布局大小
80 | st.plotly_chart(fig_contour) # 在 Streamlit 中显示等高线图
81 |
--------------------------------------------------------------------------------
/Book3_Ch13_二元函数__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch13_二元函数__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch14_Python_Codes/Bk3_Ch14_03.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 14\n",
9 | "\n",
10 | "# 斐波那契数列\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "9518a62e-6d72-4d77-b6c7-f210be3b5aff",
17 | "metadata": {},
18 | "source": [
19 | "这段代码的核心功能是生成并显示斐波那契数列的前 $n$ 项。斐波那契数列的定义是:\n",
20 | "\n",
21 | "$$\n",
22 | "F(0) = 0, \\quad F(1) = 1\n",
23 | "$$\n",
24 | "\n",
25 | "对于 $n \\geq 2$ 的情况,数列的递推关系为:\n",
26 | "\n",
27 | "$$\n",
28 | "F(n) = F(n-1) + F(n-2)\n",
29 | "$$\n",
30 | "\n",
31 | "每一项等于前两项之和,从而形成一系列逐步递增的值。代码中的函数 `fib(n)` 是递归地定义的,用于计算第 $n$ 项的值。递归关系表示,如果 $n \\leq 1$,函数直接返回 $n$;否则,它会调用自身来计算前两项 $F(n-1)$ 和 $F(n-2)$,并返回它们的和。这种递归调用直到到达基准条件,即 $F(0)$ 或 $F(1)$,从而逐步回溯并计算最终结果。\n",
32 | "\n",
33 | "在主程序中,定义了变量 `n = 10`,表示我们希望显示数列的前 $10$ 项。然后,代码通过 `for` 循环依次计算每一项 $F(i)$,从 $i = 0$ 到 $i = 9$,并打印输出。这段代码的结果是输出斐波那契数列的前 $10$ 项,通过逐项调用 `fib(i)` 函数并显示计算结果。"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "id": "85c1aae2-7f61-4f09-b193-8567ae2946ce",
39 | "metadata": {},
40 | "source": [
41 | "## 定义斐波那契数列生成函数"
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": 1,
47 | "id": "d15d8d04-e0ee-48d9-85f0-d910263dd962",
48 | "metadata": {},
49 | "outputs": [],
50 | "source": [
51 | "def fib(n):\n",
52 | " # 计算斐波那契数列第n项\n",
53 | " if n <= 1:\n",
54 | " return (n) # 如果n小于等于1,返回n\n",
55 | " else:\n",
56 | " return (fib(n-1) + fib(n-2)) # 否则递归计算前两项之和"
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "id": "cda79a3c-5f7a-4fe8-9c7a-85b488586c85",
62 | "metadata": {},
63 | "source": [
64 | "## 输出斐波那契数列的前n项"
65 | ]
66 | },
67 | {
68 | "cell_type": "code",
69 | "execution_count": 2,
70 | "id": "13119ff3-f4ae-4846-94b1-674f97bbeaba",
71 | "metadata": {},
72 | "outputs": [
73 | {
74 | "name": "stdout",
75 | "output_type": "stream",
76 | "text": [
77 | "0\n",
78 | "1\n",
79 | "1\n",
80 | "2\n",
81 | "3\n",
82 | "5\n",
83 | "8\n",
84 | "13\n",
85 | "21\n",
86 | "34\n"
87 | ]
88 | }
89 | ],
90 | "source": [
91 | "n = 10 # 设定要显示的项数\n",
92 | "for i in range(n):\n",
93 | " print(fib(i)) # 打印斐波那契数列的第i项"
94 | ]
95 | },
96 | {
97 | "cell_type": "code",
98 | "execution_count": null,
99 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
100 | "metadata": {},
101 | "outputs": [],
102 | "source": []
103 | },
104 | {
105 | "cell_type": "code",
106 | "execution_count": null,
107 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
108 | "metadata": {},
109 | "outputs": [],
110 | "source": []
111 | }
112 | ],
113 | "metadata": {
114 | "kernelspec": {
115 | "display_name": "Python 3 (ipykernel)",
116 | "language": "python",
117 | "name": "python3"
118 | },
119 | "language_info": {
120 | "codemirror_mode": {
121 | "name": "ipython",
122 | "version": 3
123 | },
124 | "file_extension": ".py",
125 | "mimetype": "text/x-python",
126 | "name": "python",
127 | "nbconvert_exporter": "python",
128 | "pygments_lexer": "ipython3",
129 | "version": "3.12.7"
130 | }
131 | },
132 | "nbformat": 4,
133 | "nbformat_minor": 5
134 | }
135 |
--------------------------------------------------------------------------------
/Book3_Ch14_Python_Codes/Streamlit_Bk3_Ch14_02.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | import numpy as np # 导入 numpy,用于数值计算
9 | from matplotlib import pyplot as plt # 导入 matplotlib,用于绘图
10 | import streamlit as st # 导入 streamlit,用于创建交互界面
11 |
12 | ## 设置 Streamlit 侧边栏的交互控件
13 | with st.sidebar:
14 | st.latex('a_k = aq^{k}') # 显示几何级数公式的数学表达式
15 |
16 | a = st.slider('a', min_value=1, max_value=5, step=1) # 滑动条设置初始项 a 的值
17 | n = st.slider('k', min_value=20, max_value=50, step=5) # 滑动条设置项数 k 的值
18 | q = st.slider('q', min_value=-2.0, max_value=2.0, step=0.1) # 滑动条设置公比 q 的值
19 |
20 | ## 生成几何级数序列
21 | GP_sequence = [a * q**i for i in range(n)] # 使用列表推导式生成几何级数序列
22 | index = np.arange(1, n + 1, 1) # 生成对应的索引数组,从 1 到 n
23 |
24 | ## 创建图形并绘制几何级数
25 | fig, ax = plt.subplots() # 创建图形和坐标轴
26 | ## 设置背景透明
27 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
28 | ax.set_facecolor('none') # 设置坐标轴背景为透明
29 |
30 | plt.xlabel("Index, $k$") # 设置 x 轴标签,显示索引 k
31 | plt.ylabel("Term, $a_k$") # 设置 y 轴标签,显示序列项 $a_k$
32 | plt.plot(index, GP_sequence, marker='.', markersize=6, linestyle='None') # 绘制几何级数的散点图
33 | ax.grid(linestyle='--', linewidth=0.25, color=[0.5, 0.5, 0.5]) # 添加网格线,设置样式和颜色
34 |
35 | ## 在 Streamlit 中显示图形
36 | st.pyplot(fig)
37 |
--------------------------------------------------------------------------------
/Book3_Ch14_数列__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch14_数列__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch15_Python_Codes/Streamlit_Bk3_Ch15_03.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | import numpy as np # 导入 numpy 用于数值计算
9 | import matplotlib.pyplot as plt # 导入 matplotlib 用于绘图
10 | from matplotlib import cm # 导入 matplotlib 的 cm 用于颜色映射
11 | from sympy import latex, lambdify # 导入 sympy 的 latex 和 lambdify
12 | import streamlit as st # 导入 streamlit 用于交互式界面
13 | from sympy.abc import x # 导入 sympy 的符号变量 x
14 |
15 | ## 定义函数,用于绘制割线
16 | def plot_secant(x0, y0, x1, y1):
17 | k = (y1 - y0) / (x1 - x0) # 计算割线的斜率
18 | x = np.linspace(-1, 4, 100) # 定义 x 的取值范围
19 | secant_y_x = k * (x - x0) + y0 # 根据割线方程计算 y 值
20 | plt.plot(x, secant_y_x, color='r', linewidth=0.25) # 绘制割线
21 |
22 | ## 在 Streamlit 的侧边栏设置交互参数
23 | with st.sidebar:
24 | x0 = st.slider('Fixed point: ', min_value=0.5, max_value=1.5, step=0.1) # 固定点的 x 坐标
25 | delta_x = st.slider('Delta x: ', min_value=0.01, max_value=0.5, value=0.5, step=0.01) # 增量
26 |
27 | ## 定义目标函数
28 | f_x = x**2 # 定义目标函数 f(x)
29 | x_array = np.linspace(-1, 4, 100) # 定义 x 的取值范围
30 | f_x_fcn = lambdify(x, f_x) # 将符号函数转换为数值函数
31 | y_array = f_x_fcn(x_array) # 计算目标函数在 x_array 的值
32 |
33 | y0 = f_x_fcn(x0) # 计算固定点 x0 的函数值
34 | x1 = x0 + delta_x # 计算增量后的点 x1
35 | y1 = f_x_fcn(x1) # 计算增量后的点 x1 的函数值
36 |
37 | ## 创建图形并绘制函数曲线和割线
38 | fig, ax = plt.subplots(figsize=(8, 8)) # 创建图形和坐标轴
39 | ## 设置背景透明
40 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
41 | ax.set_facecolor('none') # 设置坐标轴背景为透明
42 |
43 | plt.plot(x_array, y_array, color='#00448A', linewidth=1.25) # 绘制目标函数曲线
44 | plt.plot(x0, y0, color='#92D050', marker='x', markersize=12) # 绘制固定点 x0
45 | plt.plot(x1, y1, color='#00448A', marker='x', markersize=12) # 绘制增量点 x1
46 |
47 | plot_secant(x0, y0, x1, y1) # 调用函数绘制割线
48 |
49 | plt.xlabel('X') # 设置 x 轴标签
50 | plt.ylabel('$y = f(x)$') # 设置 y 轴标签
51 | ax.set_title('$f(x) = %s$' % latex(f_x)) # 设置图形标题
52 | ax.set_xlim(0, 2) # 设置 x 轴范围
53 | ax.set_ylim(-1, 4) # 设置 y 轴范围
54 |
55 | ## 在 Streamlit 中显示图形
56 | st.pyplot(fig)
57 |
--------------------------------------------------------------------------------
/Book3_Ch15_导数__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch15_导数__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch16_Python_Codes/Streamlit_Bk3_Ch16_01.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | import numpy as np # 导入 numpy 用于数值计算
9 | from sympy import lambdify, diff, exp, latex # 导入 sympy 用于符号计算
10 | from sympy.abc import x, y # 定义符号变量 x 和 y
11 | from matplotlib import pyplot as plt # 导入 matplotlib 用于绘图
12 | import streamlit as st # 导入 streamlit 用于交互式界面
13 | import plotly.graph_objects as go # 导入 plotly 用于高级可视化
14 |
15 | ## 定义侧边栏选项
16 | options = ['First-order partial derivative with respect to x1', # 选项:对 x1 的一阶偏导数
17 | 'First-order partial derivative with respect to x2', # 选项:对 x2 的一阶偏导数
18 | 'Second-order partial derivative with respect to x1', # 选项:对 x1 的二阶偏导数
19 | 'Second-order partial derivative with respect to x2'] # 选项:对 x2 的二阶偏导数
20 | label = 'Choose from:' # 侧边栏标题
21 |
22 | with st.sidebar: # 创建侧边栏
23 | option_i = st.selectbox(label, options) # 下拉菜单选择计算的偏导数类型
24 |
25 | ## 创建网格点
26 | num = 301 # 网格点的数量
27 | x_array = np.linspace(-3, 3, num) # x 方向的网格点
28 | y_array = np.linspace(-3, 3, num) # y 方向的网格点
29 | xx, yy = np.meshgrid(x_array, y_array) # 创建网格点矩阵
30 |
31 | ## 定义目标函数 f(x, y)
32 | f_xy = 3 * (1 - x)**2 * exp(-(x**2) - (y + 1)**2) \
33 | - 10 * (x / 5 - x**3 - y**5) * exp(-x**2 - y**2) \
34 | - 1 / 3 * exp(-(x + 1)**2 - y**2) # 复杂函数表达式
35 | f_xy_fcn = lambdify([x, y], f_xy) # 将符号函数转换为数值函数
36 | f_xy_zz = f_xy_fcn(xx, yy) # 计算目标函数在网格点的值
37 |
38 | ## 计算偏导数
39 | df_dx = f_xy.diff(x) # 对 x 计算一阶偏导数
40 | df_dx_fcn = lambdify([x, y], df_dx) # 转换为数值函数
41 | df_dx_zz = df_dx_fcn(xx, yy) # 计算一阶偏导数在网格点的值
42 |
43 | df_dy = f_xy.diff(y) # 对 y 计算一阶偏导数
44 | df_dy_fcn = lambdify([x, y], df_dy) # 转换为数值函数
45 | df_dy_zz = df_dy_fcn(xx, yy) # 计算一阶偏导数在网格点的值
46 |
47 | d2f_dxdx = f_xy.diff(x, 2) # 对 x 计算二阶偏导数
48 | d2f_dxdx_fcn = lambdify([x, y], d2f_dxdx) # 转换为数值函数
49 | d2f_dxdx_zz = d2f_dxdx_fcn(xx, yy) # 计算二阶偏导数在网格点的值
50 |
51 | d2f_dydy = f_xy.diff(y, 2) # 对 y 计算二阶偏导数
52 | d2f_dydy_fcn = lambdify([x, y], d2f_dydy) # 转换为数值函数
53 | d2f_dydy_zz = d2f_dydy_fcn(xx, yy) # 计算二阶偏导数在网格点的值
54 |
55 | ## 根据选项选择偏导数进行可视化
56 | if option_i == 'First-order partial derivative with respect to x1': # 如果选择对 x1 的一阶偏导数
57 | st.latex(r'\frac{\partial{f}}{\partial{x_1}}') # 显示数学公式
58 | ff = df_dx_zz # 设置可视化数据为对 x1 的一阶偏导数
59 |
60 | elif option_i == 'First-order partial derivative with respect to x2': # 如果选择对 x2 的一阶偏导数
61 | st.latex(r'\frac{\partial{f}}{\partial{x_2}}') # 显示数学公式
62 | ff = df_dy_zz # 设置可视化数据为对 x2 的一阶偏导数
63 |
64 | elif option_i == 'Second-order partial derivative with respect to x1': # 如果选择对 x1 的二阶偏导数
65 | st.latex(r'\frac{\partial^2{f}}{\partial{x_1^2}}') # 显示数学公式
66 | ff = d2f_dxdx_zz # 设置可视化数据为对 x1 的二阶偏导数
67 |
68 | elif option_i == 'Second-order partial derivative with respect to x2': # 如果选择对 x2 的二阶偏导数
69 | st.latex(r'\frac{\partial^2{f}}{\partial{x_2^2}}') # 显示数学公式
70 | ff = d2f_dydy_zz # 设置可视化数据为对 x2 的二阶偏导数
71 |
72 | ## 使用 plotly 进行三维曲面图可视化
73 | fig_surface = go.Figure(go.Surface(
74 | x=x_array, # 设置 x 轴数据
75 | y=y_array, # 设置 y 轴数据
76 | z=ff, # 设置 z 轴数据为选中的偏导数值
77 | showscale=False, # 不显示颜色条
78 | colorscale='RdYlBu_r' # 设置颜色样式
79 | ))
80 | fig_surface.update_layout(
81 | # autosize=True, # 自动调整大小
82 | width=800, # 设置图形宽度
83 | height=600 # 设置图形高度
84 | )
85 | st.plotly_chart(fig_surface) # 在 Streamlit 中展示三维曲面图
86 |
87 | ## 使用 plotly 进行等高线图可视化
88 | fig_contour = go.Figure(data=go.Contour(
89 | z=ff, # 设置 z 轴数据为选中的偏导数值
90 | x=x_array, # 设置 x 轴数据
91 | y=y_array, # 设置 y 轴数据
92 | colorscale='RdYlBu_r' # 设置颜色样式
93 | ))
94 | fig_contour.update_layout(
95 | # autosize=True, # 自动调整大小
96 | width=600, # 设置图形宽度
97 | height=600 # 设置图形高度
98 | )
99 | st.plotly_chart(fig_contour) # 在 Streamlit 中展示等高线图
100 |
--------------------------------------------------------------------------------
/Book3_Ch16_偏导数__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch16_偏导数__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch17_Python_Codes/Streamlit_Bk3_Ch17_01.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | from sympy import lambdify, diff, evalf, exp # 导入Sympy的相关函数和工具,用于符号计算
9 | from sympy.abc import x # 定义符号变量x
10 | import numpy as np # 导入NumPy,用于数值计算
11 | from matplotlib import pyplot as plt # 导入Matplotlib,用于绘图
12 | import streamlit as st # 导入Streamlit,用于交互式应用
13 |
14 | ## 在侧边栏设置用户选择 ##
15 | with st.sidebar:
16 | option_i = st.selectbox('Choose from:', # 用户选择泰勒展开的阶数
17 | ['First-order approximation', # 一阶近似
18 | 'Second-order approximation']) # 二阶近似
19 | x_0 = st.slider('Expansion point:', # 设置泰勒展开点
20 | min_value=-2.5, # 最小值
21 | max_value=2.5, # 最大值
22 | step=0.1) # 步长
23 |
24 | ## 定义函数和相关参数 ##
25 | f_x = exp(-x**2) # 定义原函数f(x) = e^(-x^2)
26 | x_array = np.linspace(-3, 3, 100) # 在区间[-3, 3]生成100个x值
27 | f_x_fcn = lambdify(x, f_x) # 将符号函数转换为可执行函数
28 | f_x_array = f_x_fcn(x_array) # 计算原函数在x_array上的值
29 |
30 | ## 计算导数 ##
31 | f_x_1_diff = diff(f_x, x) # 计算f(x)的一阶导数
32 | f_x_1_diff_fcn = lambdify(x, f_x_1_diff) # 将一阶导数转换为可执行函数
33 |
34 | f_x_2_diff = diff(f_x, x, 2) # 计算f(x)的二阶导数
35 | f_x_2_diff_fcn = lambdify(x, f_x_2_diff) # 将二阶导数转换为可执行函数
36 |
37 | ## 创建图形 ##
38 | fig, ax = plt.subplots() # 创建绘图对象
39 | ax.plot(x_array, f_x_array, linewidth=1.5) # 绘制原函数f(x)
40 | ax.set_xlabel("$\it{x}$") # 设置x轴标签
41 | ax.set_ylabel("$\it{f}(\it{x})$") # 设置y轴标签
42 |
43 | ## 计算泰勒展开的近似 ##
44 | y_0 = f_x.evalf(subs={x: x_0}) # 计算f(x_0)的值
45 | x_t_array = np.linspace(x_0 - 0.5, x_0 + 0.5, 50) # 生成展开点附近的x值
46 |
47 | b = f_x_1_diff.evalf(subs={x: x_0}) # 计算f'(x_0)的值
48 | a = f_x_2_diff.evalf(subs={x: x_0}) # 计算f''(x_0)的值
49 |
50 | if option_i == 'First-order approximation': # 如果选择一阶近似
51 | approx_f = b * (x - x_0) + y_0 # 定义一阶泰勒展开公式
52 | approx_f_fcn = lambdify(x, approx_f) # 将一阶展开公式转换为可执行函数
53 | approx_f_array = approx_f_fcn(x_t_array) # 计算近似值
54 | else: # 如果选择二阶近似
55 | approx_f = a / 2 * (x - x_0)**2 + b * (x - x_0) + y_0 # 定义二阶泰勒展开公式
56 | approx_f_fcn = lambdify(x, approx_f) # 将二阶展开公式转换为可执行函数
57 | approx_f_array = approx_f_fcn(x_t_array) # 计算近似值
58 |
59 | if type(approx_f_array) == float: # 如果结果是单个浮点数
60 | approx_f_array = approx_f_array + x_t_array * 0 # 扩展为与x_t_array相同长度的数组
61 |
62 | ## 绘制近似曲线和展开点 ##
63 | ax.plot(x_t_array, approx_f_array, linewidth=0.25, color='r') # 绘制近似曲线
64 | ax.plot(x_0, y_0, marker='.', color='r', markersize=12) # 标记展开点
65 | ax.grid(linestyle='--', linewidth=0.25, color=[0.5, 0.5, 0.5]) # 设置网格线
66 | ax.set_xlim(-3, 3) # 设置x轴范围
67 | ax.set_ylim(-0.25, 1.25) # 设置y轴范围
68 | ## 设置背景透明
69 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
70 | ax.set_facecolor('none') # 设置坐标轴背景为透明
71 | ## 使用Streamlit显示图形 ##
72 | st.pyplot(fig) # 在Streamlit界面显示图形
73 |
--------------------------------------------------------------------------------
/Book3_Ch17_Python_Codes/Streamlit_Bk3_Ch17_02.py:
--------------------------------------------------------------------------------
1 |
2 | ###############
3 | # Authored by Weisheng Jiang
4 | # Book 3 | From Basic Arithmetic to Machine Learning
5 | # Published and copyrighted by Tsinghua University Press
6 | # Beijing, China, 2025
7 | ###############
8 |
9 |
10 | from sympy import latex, lambdify, diff, sin, log, exp, series
11 | from sympy.abc import x
12 | import numpy as np
13 | from matplotlib import pyplot as plt
14 | from matplotlib import cm
15 | import streamlit as st
16 |
17 | #%%
18 |
19 | with st.sidebar:
20 |
21 | p = st.slider('Define the degree of polynomial:',
22 | min_value = 1,
23 | max_value = 10,
24 | step = 1)
25 |
26 |
27 | #%%
28 |
29 |
30 | f_x = exp(x)
31 | x_array = np.linspace(-2,2,100)
32 | x_0 = 0 # expansion point
33 |
34 | y_0 = f_x.evalf(subs = {x: x_0})
35 |
36 | f_x_fcn = lambdify(x,f_x)
37 | f_x_array = f_x_fcn(x_array)
38 |
39 |
40 | #%% Visualizations
41 |
42 | fig = plt.figure(figsize=plt.figaspect(0.5))
43 | ax = fig.add_subplot(1, 2, 1)
44 | ## 设置背景透明
45 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
46 | ax.set_facecolor('none') # 设置坐标轴背景为透明
47 | ax.plot(x_array, f_x_array, 'k', linewidth = 1.5)
48 | ax.plot(x_0, y_0, 'xr', markersize = 12)
49 | ax.set_xlabel("$\it{x}$")
50 | ax.set_ylabel("$\it{f}(\it{x})$")
51 |
52 |
53 | f_series = f_x.series(x,x_0,p + 1).removeO()
54 | # order + 1 = number of terms
55 |
56 | f_series_fcn = lambdify(x,f_series)
57 | f_series_array = f_series_fcn(x_array)
58 | f_series_array = x_array*0 + f_series_array
59 |
60 | ax.plot(x_array, f_series_array, linewidth = 1.5,
61 | color = 'b')
62 |
63 | ax.fill_between(x_array,
64 | f_x_array,
65 | x_array*0 + f_series_array,
66 | color = '#DEEAF6')
67 |
68 | ax.grid(linestyle='--', linewidth=0.25, color=[0.5,0.5,0.5])
69 | ax.set_xlim(x_array.min(),x_array.max())
70 |
71 | ax.set_ylim(np.floor(f_x_array.min()),
72 | np.ceil(f_x_array.max()))
73 | # ax.set_aspect('equal', 'box')
74 | # plt.legend()
75 | ax.spines['right'].set_visible(False)
76 | ax.spines['top'].set_visible(False)
77 |
78 | ax = fig.add_subplot(1, 2, 2)
79 | ## 设置背景透明
80 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
81 | ax.set_facecolor('none') # 设置坐标轴背景为透明
82 | error = f_x_array - f_series_array
83 | ax.plot(x_array, error, 'r', linewidth = 1.5)
84 | ax.fill_between(x_array,
85 | error,
86 | color = '#DEEAF6')
87 | plt.axhline(y=0, color='k', linestyle='--', linewidth = 0.25)
88 | ax.set_xlabel("$\it{x}$")
89 | ax.set_ylabel("Error")
90 |
91 | ax.grid(linestyle='--', linewidth=0.25, color=[0.5,0.5,0.5])
92 | ax.set_xlim(x_array.min(),x_array.max())
93 | ax.set_ylim(-1,5)
94 | ax.spines['right'].set_visible(False)
95 | ax.spines['top'].set_visible(False)
96 |
97 | st.pyplot(fig)
--------------------------------------------------------------------------------
/Book3_Ch17_微分__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch17_微分__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch18_Python_Codes/Bk3_Ch18_04.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 18\n",
9 | "\n",
10 | "# 二元高斯函数积分\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "28e07edf-9705-45c3-9a49-219e1dd350c0",
17 | "metadata": {},
18 | "source": [
19 | "这段代码通过积分计算高斯函数\n",
20 | "\n",
21 | "$$\n",
22 | "f(x, y) = e^{-x^2 - y^2}\n",
23 | "$$\n",
24 | "\n",
25 | "在不同区域上的累积面积和总体面积。\n",
26 | "\n",
27 | "1. **累积积分**:首先,代码计算了从 $(-\\infty, -\\infty)$ 到 $(x, y)$ 的累积积分\n",
28 | "\n",
29 | " $$\n",
30 | " F(x, y) = \\int_{-\\infty}^x \\int_{-\\infty}^y e^{-u^2 - v^2} \\, dv \\, du\n",
31 | " $$\n",
32 | "\n",
33 | " 该积分表示从左下角到点 $(x, y)$ 之间区域内函数 $f(x, y)$ 的累积面积。累积积分在概率论中常用于描述二维正态分布中的累积概率,表示该区域内的概率密度累积。\n",
34 | "\n",
35 | "2. **体积积分**:其次,代码计算了 $f(x, y)$ 在整个 $xy$ 平面上的积分,即从 $(-\\infty, -\\infty)$ 到 $(\\infty, \\infty)$ 的积分。这相当于计算 $f(x, y)$ 在无穷大区域内的总面积(或体积):\n",
36 | "\n",
37 | " $$\n",
38 | " \\int_{-\\infty}^{\\infty} \\int_{-\\infty}^{\\infty} e^{-x^2 - y^2} \\, dx \\, dy = \\pi\n",
39 | " $$\n",
40 | "\n",
41 | " 此结果表明,在整个平面上积分,二维高斯函数的面积是有限的,为 $\\pi$。这表示标准二维正态分布的总概率密度,揭示了高斯分布的收敛特性。代码通过计算展示了该函数的局部累积行为和总体特性。"
42 | ]
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "id": "a09643a6-0e97-4823-8ff8-7173cacfdae9",
47 | "metadata": {},
48 | "source": [
49 | "## 导入包"
50 | ]
51 | },
52 | {
53 | "cell_type": "code",
54 | "execution_count": 1,
55 | "id": "e457bcfd-9e71-4224-b5bf-93c69be2d5a3",
56 | "metadata": {},
57 | "outputs": [],
58 | "source": [
59 | "from sympy.abc import x, y, s, t # 定义符号变量 x, y, s, t\n",
60 | "from sympy import * # 导入符号计算库"
61 | ]
62 | },
63 | {
64 | "cell_type": "code",
65 | "execution_count": 2,
66 | "id": "ece5b932-2c75-4b54-a107-47e22a2e17f8",
67 | "metadata": {},
68 | "outputs": [
69 | {
70 | "data": {
71 | "text/latex": [
72 | "$\\displaystyle e^{- x^{2} - y^{2}}$"
73 | ],
74 | "text/plain": [
75 | "exp(-x**2 - y**2)"
76 | ]
77 | },
78 | "execution_count": 2,
79 | "metadata": {},
80 | "output_type": "execute_result"
81 | }
82 | ],
83 | "source": [
84 | "f_xy = exp(- x**2 - y**2) # 定义函数 f(x, y) = exp(-x^2 - y^2)\n",
85 | "f_xy"
86 | ]
87 | },
88 | {
89 | "cell_type": "markdown",
90 | "id": "661e667b-7768-47b8-a2f2-50d2b1b0f34a",
91 | "metadata": {},
92 | "source": [
93 | "## 计算累积积分"
94 | ]
95 | },
96 | {
97 | "cell_type": "code",
98 | "execution_count": 3,
99 | "id": "ce6b2d77-460f-46d9-90b9-24dadd8af54f",
100 | "metadata": {},
101 | "outputs": [
102 | {
103 | "data": {
104 | "text/latex": [
105 | "$\\displaystyle \\frac{\\pi \\operatorname{erf}{\\left(x \\right)} \\operatorname{erf}{\\left(y \\right)}}{4} + \\frac{\\pi \\operatorname{erf}{\\left(x \\right)}}{4} + \\frac{\\pi \\operatorname{erf}{\\left(y \\right)}}{4} + \\frac{\\pi}{4}$"
106 | ],
107 | "text/plain": [
108 | "pi*erf(x)*erf(y)/4 + pi*erf(x)/4 + pi*erf(y)/4 + pi/4"
109 | ]
110 | },
111 | "execution_count": 3,
112 | "metadata": {},
113 | "output_type": "execute_result"
114 | }
115 | ],
116 | "source": [
117 | "f_x_y_double_integrate = integrate(f_xy, (y, -oo, y), (x, -oo, x)) # 计算从 (-∞, -∞) 到 (x, y) 的累积积分\n",
118 | "f_x_y_double_integrate"
119 | ]
120 | },
121 | {
122 | "cell_type": "markdown",
123 | "id": "57114b91-fd59-466c-8dd9-3c945ad862fb",
124 | "metadata": {},
125 | "source": [
126 | "## 计算体积积分"
127 | ]
128 | },
129 | {
130 | "cell_type": "code",
131 | "execution_count": 4,
132 | "id": "8b1e2579-5f39-4b39-8993-85c4f8430465",
133 | "metadata": {},
134 | "outputs": [
135 | {
136 | "name": "stdout",
137 | "output_type": "stream",
138 | "text": [
139 | "pi\n"
140 | ]
141 | }
142 | ],
143 | "source": [
144 | "f_x_y_volume = integrate(f_xy, (y, -oo, oo), (x, -oo, oo)) # 计算整个平面上的积分(对应体积)\n",
145 | "print(f_x_y_volume)"
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": null,
151 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
152 | "metadata": {},
153 | "outputs": [],
154 | "source": []
155 | },
156 | {
157 | "cell_type": "code",
158 | "execution_count": null,
159 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
160 | "metadata": {},
161 | "outputs": [],
162 | "source": []
163 | }
164 | ],
165 | "metadata": {
166 | "kernelspec": {
167 | "display_name": "Python 3 (ipykernel)",
168 | "language": "python",
169 | "name": "python3"
170 | },
171 | "language_info": {
172 | "codemirror_mode": {
173 | "name": "ipython",
174 | "version": 3
175 | },
176 | "file_extension": ".py",
177 | "mimetype": "text/x-python",
178 | "name": "python",
179 | "nbconvert_exporter": "python",
180 | "pygments_lexer": "ipython3",
181 | "version": "3.12.7"
182 | }
183 | },
184 | "nbformat": 4,
185 | "nbformat_minor": 5
186 | }
187 |
--------------------------------------------------------------------------------
/Book3_Ch18_Python_Codes/Bk3_Ch18_05.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 18\n",
9 | "\n",
10 | "# 偏积分\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "def700bf-df83-4e28-ab65-f840c63791fe",
17 | "metadata": {},
18 | "source": [
19 | "这段代码计算了二维高斯函数\n",
20 | "\n",
21 | "$$\n",
22 | "f(x, y) = e^{-x^2 - y^2}\n",
23 | "$$\n",
24 | "\n",
25 | "在两个独立方向上的偏积分,从而将原始的二维函数简化为一维表达形式。\n",
26 | "\n",
27 | "1. **对 $y$ 的积分**:首先,代码对 $f(x, y)$ 在 $y \\in (-\\infty, \\infty)$ 上进行积分,结果为\n",
28 | "\n",
29 | " $$\n",
30 | " \\int_{-\\infty}^{\\infty} e^{-x^2 - y^2} \\, dy = \\sqrt{\\pi} e^{-x^2}\n",
31 | " $$\n",
32 | "\n",
33 | " 该结果表示在 $y$ 方向上的累积效应,产生一个关于 $x$ 的一维高斯函数形式。这表明在 $y$ 上积分后,函数的概率密度沿 $x$ 方向保持高斯分布。\n",
34 | "\n",
35 | "2. **对 $x$ 的积分**:然后,代码对 $f(x, y)$ 在 $x \\in (-\\infty, \\infty)$ 上进行积分,结果为\n",
36 | "\n",
37 | " $$\n",
38 | " \\int_{-\\infty}^{\\infty} e^{-x^2 - y^2} \\, dx = \\sqrt{\\pi} e^{-y^2}\n",
39 | " $$\n",
40 | "\n",
41 | " 这给出了 $x$ 方向上的累积效应,得到关于 $y$ 的一维高斯函数形式。说明在 $x$ 上积分后,函数的概率密度沿 $y$ 方向仍然保持高斯分布。\n",
42 | "\n",
43 | "通过这些偏积分,代码展示了二维高斯函数在单个方向上积分后,如何保留另一变量的高斯分布性质。这些计算是多维高斯函数性质的关键,揭示了高斯分布的独立性和累积行为。"
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "id": "29f75535-48d4-4a18-a5c7-bbcd185ac65c",
49 | "metadata": {},
50 | "source": [
51 | "## 导入包"
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": 1,
57 | "id": "3ae4d8b0-4681-4672-852f-b92fe862f3d8",
58 | "metadata": {},
59 | "outputs": [],
60 | "source": [
61 | "from sympy.abc import x, y, s, t # 导入符号变量 x, y, s, t\n",
62 | "from sympy import * # 导入符号计算库"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": 2,
68 | "id": "5e041c3d-f2cf-4a75-af63-5ae4c8fda321",
69 | "metadata": {},
70 | "outputs": [
71 | {
72 | "data": {
73 | "text/latex": [
74 | "$\\displaystyle e^{- x^{2} - y^{2}}$"
75 | ],
76 | "text/plain": [
77 | "exp(-x**2 - y**2)"
78 | ]
79 | },
80 | "execution_count": 2,
81 | "metadata": {},
82 | "output_type": "execute_result"
83 | }
84 | ],
85 | "source": [
86 | "f_xy = exp(- x**2 - y**2) # 定义函数 f(x, y) = exp(-x^2 - y^2)\n",
87 | "f_xy"
88 | ]
89 | },
90 | {
91 | "cell_type": "markdown",
92 | "id": "89fb2d8a-6291-4732-898e-52f97d9a2c29",
93 | "metadata": {},
94 | "source": [
95 | "## 对 y 进行偏积分"
96 | ]
97 | },
98 | {
99 | "cell_type": "code",
100 | "execution_count": 3,
101 | "id": "66d8b977-dfe7-4622-a026-1057185dcb9c",
102 | "metadata": {},
103 | "outputs": [
104 | {
105 | "data": {
106 | "text/latex": [
107 | "$\\displaystyle \\sqrt{\\pi} e^{- x^{2}}$"
108 | ],
109 | "text/plain": [
110 | "sqrt(pi)*exp(-x**2)"
111 | ]
112 | },
113 | "execution_count": 3,
114 | "metadata": {},
115 | "output_type": "execute_result"
116 | }
117 | ],
118 | "source": [
119 | "f_x_partial_integrate = integrate(f_xy, (y, -oo, oo)) # 计算 f(x, y) 在 y 方向上的偏积分\n",
120 | "f_x_partial_integrate"
121 | ]
122 | },
123 | {
124 | "cell_type": "markdown",
125 | "id": "62f508d4-c704-4962-afb2-cc169d5e819f",
126 | "metadata": {},
127 | "source": [
128 | "## 对 x 进行偏积分"
129 | ]
130 | },
131 | {
132 | "cell_type": "code",
133 | "execution_count": 4,
134 | "id": "0b01b449-3ff1-4d8e-9e40-21af30ab4944",
135 | "metadata": {},
136 | "outputs": [
137 | {
138 | "data": {
139 | "text/latex": [
140 | "$\\displaystyle \\sqrt{\\pi} e^{- y^{2}}$"
141 | ],
142 | "text/plain": [
143 | "sqrt(pi)*exp(-y**2)"
144 | ]
145 | },
146 | "execution_count": 4,
147 | "metadata": {},
148 | "output_type": "execute_result"
149 | }
150 | ],
151 | "source": [
152 | "f_y_partial_integrate = integrate(f_xy, (x, -oo, oo)) # 计算 f(x, y) 在 x 方向上的偏积分\n",
153 | "f_y_partial_integrate"
154 | ]
155 | },
156 | {
157 | "cell_type": "code",
158 | "execution_count": null,
159 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
160 | "metadata": {},
161 | "outputs": [],
162 | "source": []
163 | },
164 | {
165 | "cell_type": "code",
166 | "execution_count": null,
167 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
168 | "metadata": {},
169 | "outputs": [],
170 | "source": []
171 | }
172 | ],
173 | "metadata": {
174 | "kernelspec": {
175 | "display_name": "Python 3 (ipykernel)",
176 | "language": "python",
177 | "name": "python3"
178 | },
179 | "language_info": {
180 | "codemirror_mode": {
181 | "name": "ipython",
182 | "version": 3
183 | },
184 | "file_extension": ".py",
185 | "mimetype": "text/x-python",
186 | "name": "python",
187 | "nbconvert_exporter": "python",
188 | "pygments_lexer": "ipython3",
189 | "version": "3.12.7"
190 | }
191 | },
192 | "nbformat": 4,
193 | "nbformat_minor": 5
194 | }
195 |
--------------------------------------------------------------------------------
/Book3_Ch18_Python_Codes/Streamlit_Bk3_Ch18_07.py:
--------------------------------------------------------------------------------
1 | import numpy as np # 导入 numpy 库,用于数值计算
2 | import matplotlib.pyplot as plt # 导入 matplotlib.pyplot 库,用于数据可视化
3 | from sympy import * # 导入 sympy 库,用于符号计算
4 | import streamlit as st # 导入 streamlit 库,用于创建交互式应用
5 |
6 | ## 侧边栏:设置积分区间的数量
7 | with st.sidebar:
8 | # 创建滑块,用于选择积分区间数量
9 | num_intervals = st.slider('Number of intervals:',
10 | min_value=5, # 最小值为 5
11 | max_value=50, # 最大值为 50
12 | step=1) # 步长为 1
13 |
14 | ## 定义符号函数和积分区间
15 | x = Symbol('x') # 定义符号变量 x
16 | f_x = x**2 # 定义被积函数为 f(x) = x^2
17 |
18 | # 将符号函数转换为可执行函数
19 | f_x_fcn = lambdify([x], f_x)
20 |
21 | # 计算 f(x) 的不定积分
22 | integral_f_x = integrate(f_x, x)
23 | # 将不定积分转换为可执行函数
24 | integral_f_x_fcn = lambdify([x], integral_f_x)
25 |
26 | a = 0 # 积分下限
27 | b = 1 # 积分上限
28 |
29 | # 计算定积分的值
30 | integral_a_b = integral_f_x_fcn(b) - integral_f_x_fcn(a)
31 |
32 | # 使用符号库直接计算定积分
33 | integral_a_b_v2 = integrate(f_x, (x, a, b))
34 | integral_a_b_v2 = float(integral_a_b_v2) # 转换为浮点数
35 |
36 | # 打印定积分的值
37 | print('$\\int_a^b f(x)dx = %0.3f$' % integral_a_b)
38 |
39 | ## 可视化部分
40 |
41 | # 计算区间宽度
42 | delta_x = (b - a) / num_intervals
43 |
44 | # 生成积分区间的节点
45 | x_array = np.linspace(a, b, num_intervals + 1)
46 | # 计算对应的函数值
47 | y_array = f_x_fcn(x_array)
48 |
49 | # 生成更密集的节点,用于绘制函数曲线
50 | x_array_fine = np.linspace(a, b, 200)
51 | y_array_fine = f_x_fcn(x_array_fine)
52 |
53 | # 创建图形,设置大小
54 | fig = plt.figure(figsize=(15, 5))
55 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
56 | ## 左矩形法 Riemann 和
57 | ax = fig.add_subplot(1, 3, 1) # 创建子图 1
58 | ## 设置背景透明
59 | # fig.patch.set_alpha(0) # 设置整个图形背景为透明
60 | ax.set_facecolor('none') # 设置坐标轴背景为透明
61 | # 绘制函数曲线
62 | plt.plot(x_array_fine, y_array_fine, color='#0070C0')
63 |
64 | # 获取左端点
65 | x_left = x_array[:-1]
66 | y_left = y_array[:-1]
67 |
68 | # 绘制左端点
69 | plt.plot(x_left, y_left, 'rx', markersize=10)
70 |
71 | # 绘制矩形
72 | plt.bar(x_left, y_left,
73 | width=delta_x, # 矩形宽度为区间宽度
74 | facecolor='#DEEAF6', # 矩形填充颜色
75 | align='edge', # 矩形对齐左端点
76 | edgecolor='#B2B2B2') # 矩形边框颜色
77 |
78 | # 绘制积分上下限的垂直线
79 | ax.axvline(x=a, color='r', linestyle='-')
80 | ax.axvline(x=b, color='r', linestyle='-')
81 |
82 | # 计算左矩形法的 Riemann 和
83 | left_riemann_sum = np.sum(f_x_fcn(x_left) * delta_x)
84 |
85 | # 设置标题
86 | plt.title('Left Riemann sum (N = %0.0f) = %0.3f'
87 | % (num_intervals, left_riemann_sum))
88 | plt.xlim((a, b)) # 设置 x 轴范围
89 | plt.gca().spines['right'].set_visible(False) # 隐藏右边框
90 | plt.gca().spines['top'].set_visible(False) # 隐藏上边框
91 | plt.xlabel('x') # 设置 x 轴标签
92 | plt.ylabel('f(x)') # 设置 y 轴标签
93 |
94 | ## 中矩形法 Riemann 和
95 | ax = fig.add_subplot(1, 3, 2) # 创建子图 2
96 | ## 设置背景透明
97 |
98 | ax.set_facecolor('none') # 设置坐标轴背景为透明
99 | # 绘制函数曲线
100 | plt.plot(x_array_fine, y_array_fine, color='#0070C0')
101 |
102 | # 计算中点
103 | x_mid = (x_array[:-1] + x_array[1:]) / 2
104 | y_mid = f_x_fcn(x_mid)
105 |
106 | # 绘制中点
107 | plt.plot(x_mid, y_mid, 'rx', markersize=10)
108 |
109 | # 绘制矩形
110 | plt.bar(x_mid, y_mid,
111 | width=delta_x,
112 | facecolor='#DEEAF6',
113 | edgecolor='#B2B2B2')
114 |
115 | # 绘制积分上下限的垂直线
116 | ax.axvline(x=a, color='r', linestyle='-')
117 | ax.axvline(x=b, color='r', linestyle='-')
118 |
119 | # 计算中矩形法的 Riemann 和
120 | mid_riemann_sum = np.sum(f_x_fcn(x_mid) * delta_x)
121 |
122 | # 设置标题
123 | plt.title('Middle Riemann sum (N = %0.0f) = %0.3f'
124 | % (num_intervals, mid_riemann_sum))
125 | plt.xlim((a, b))
126 | plt.gca().spines['right'].set_visible(False)
127 | plt.gca().spines['top'].set_visible(False)
128 | plt.xlabel('x')
129 | plt.ylabel('f(x)')
130 |
131 | ## 右矩形法 Riemann 和
132 | ax = fig.add_subplot(1, 3, 3) # 创建子图 3
133 | ## 设置背景透明
134 | # fig.patch.set_alpha(0) # 设置整个图形背景为透明
135 | ax.set_facecolor('none') # 设置坐标轴背景为透明
136 | # 绘制函数曲线
137 | plt.plot(x_array_fine, y_array_fine, color='#0070C0')
138 |
139 | # 获取右端点
140 | x_right = x_array[1:]
141 | y_right = y_array[1:]
142 |
143 | # 绘制右端点
144 | plt.plot(x_right, y_right, 'rx', markersize=10)
145 |
146 | # 绘制矩形
147 | plt.bar(x_right, y_right,
148 | width=delta_x,
149 | facecolor='#DEEAF6',
150 | align='edge',
151 | edgecolor='#B2B2B2')
152 |
153 | # 绘制积分上下限的垂直线
154 | ax.axvline(x=a, color='r', linestyle='-')
155 | ax.axvline(x=b, color='r', linestyle='-')
156 |
157 | # 计算右矩形法的 Riemann 和
158 | right_riemann_sum = np.sum(f_x_fcn(x_right) * delta_x)
159 |
160 | # 设置标题
161 | plt.title('Right Riemann sum (N = %0.0f) = %0.3f'
162 | % (num_intervals, right_riemann_sum))
163 | plt.xlim((a, b))
164 | plt.gca().spines['right'].set_visible(False)
165 | plt.gca().spines['top'].set_visible(False)
166 | plt.xlabel('x')
167 | plt.ylabel('f(x)')
168 |
169 | # 在 Streamlit 中展示图形
170 | st.pyplot(fig)
171 |
--------------------------------------------------------------------------------
/Book3_Ch18_积分__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch18_积分__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch19_优化入门__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch19_优化入门__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch20_Python_Codes/Streamlit_Bk3_Ch20_01.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | ## 导入必要的库
9 | from matplotlib import pyplot as plt # 导入 Matplotlib 库用于绘图
10 | import numpy as np # 导入 NumPy 库用于数组操作
11 | from sympy.abc import x # 从 SymPy 中导入符号变量 x
12 | from sympy import Poly # 从 SymPy 中导入多项式类
13 | import seaborn as sns # 导入 Seaborn 库用于高级绘图
14 | import streamlit as st # 导入 Streamlit 库用于创建交互式 Web 应用
15 |
16 | ## 创建 Streamlit 的侧边栏控件
17 | with st.sidebar: # 定义侧边栏内容
18 | n = st.slider('Number of steps:', # 创建滑块用于选择步数
19 | min_value=2, # 最小值为 2
20 | max_value=20, # 最大值为 20
21 | step=1) # 步进值为 1
22 |
23 | p = st.slider('Probability, p', # 创建滑块用于选择概率 p
24 | min_value=0.1, # 最小值为 0.1
25 | max_value=0.9, # 最大值为 0.9
26 | step=0.1) # 步进值为 0.1
27 |
28 | ## 绘制概率直方图和二叉树路径
29 |
30 | from scipy.stats import binom # 从 SciPy 库中导入二项分布模块
31 |
32 | x = np.arange(0, n + 1) # 创建范围为 [0, n] 的整数数组
33 |
34 | p_x = binom.pmf(x, n, p) # 计算二项分布概率质量函数 (PMF)
35 |
36 | fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5), gridspec_kw={'width_ratios': [3, 1]}) # 创建包含两个子图的图形
37 | ## 设置背景透明
38 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
39 | ax1.set_facecolor('none') # 设置坐标轴背景为透明
40 | ax2.set_facecolor('none') # 设置坐标轴背景为透明
41 |
42 | for i in np.arange(n): # 遍历二叉树的每一层
43 | Nodes_y = np.linspace(-i, i, i + 1) # 计算当前层的节点 y 坐标
44 |
45 | B_y = np.concatenate((Nodes_y + 1, Nodes_y - 1)) # 计算下一层的节点 y 坐标
46 | B_x = np.zeros_like(B_y) + i + 1 # 下一层的节点 x 坐标
47 | B = np.stack((B_x, B_y)) # 将 x 和 y 坐标堆叠成二维数组
48 |
49 | A_y = np.concatenate((Nodes_y, Nodes_y)) # 当前层的节点 y 坐标
50 | A_x = np.zeros_like(A_y) + i # 当前层的节点 x 坐标
51 |
52 | x_AB = np.stack((A_x, B_x)) # 当前层到下一层的 x 坐标连接
53 | y_AB = np.stack((A_y, B_y)) # 当前层到下一层的 y 坐标连接
54 |
55 | ax1.plot(x_AB, y_AB, 'o-', color='#92D050', # 在二叉树中绘制节点和边
56 | markerfacecolor='#0099FF',
57 | markeredgecolor=None)
58 |
59 | locations = np.linspace(B_y.min(), B_y.max(), n + 1) # 计算直方图的 y 坐标位置
60 |
61 | ax1.spines['right'].set_visible(False) # 隐藏右边框
62 | ax1.spines['top'].set_visible(False) # 隐藏上边框
63 |
64 | ax1.set_xlim(0, n) # 设置 x 轴范围
65 | ax1.set_ylim(B_y.min() - 1, B_y.max() + 1) # 设置 y 轴范围
66 |
67 | ax2.barh(locations, p_x, align='center') # 绘制概率直方图
68 |
69 | for i, (x, y) in enumerate(zip(locations.tolist(), p_x.tolist())): # 遍历每个直方图条目
70 | ax2.text(y + p_x.max() * 0.1, x, "{:.4f}".format(y)) # 在条目旁显示概率值
71 |
72 | ax2.set_ylim(B_y.min() - 1, B_y.max() + 1) # 设置直方图 y 轴范围
73 | ax2.spines['right'].set_visible(False) # 隐藏右边框
74 | ax2.spines['top'].set_visible(False) # 隐藏上边框
75 |
76 | st.pyplot(fig) # 使用 Streamlit 显示绘制的图形
77 |
--------------------------------------------------------------------------------
/Book3_Ch20_Python_Codes/Streamlit_Bk3_Ch20_02.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import plotly.graph_objects as go
3 | import streamlit as st
4 |
5 | # 在 Streamlit 侧边栏设置参数
6 | with st.sidebar:
7 | num_toss = st.slider('Number of toss:',
8 | min_value=50,
9 | max_value=200,
10 | step=1) # 设置抛硬币次数
11 | rnd_seed = st.slider('Random seed number',
12 | min_value=0,
13 | max_value=100,
14 | step=1) # 设置随机种子
15 |
16 | # 设置随机种子
17 | np.random.seed(rnd_seed)
18 |
19 | # 生成抛硬币结果(0 表示正面,1 表示反面)
20 | toss = np.random.randint(low=0, high=2, size=(num_toss, 1))
21 |
22 | # 计算每次抛硬币的累积均值
23 | iteration = np.arange(1, num_toss + 1) # 生成迭代序列
24 | cum_mean = np.cumsum(toss) / iteration # 计算累积均值
25 |
26 | # 创建第一幅图:抛硬币的散点图
27 | scatter_fig = go.Figure()
28 |
29 | # 添加正面的散点
30 | scatter_fig.add_trace(go.Scatter(
31 | x=iteration[toss.flatten() == 1],
32 | y=toss[toss == 1].flatten(),
33 | mode='markers',
34 | marker=dict(color='red', size=6),
35 | name='Head (1)'
36 | ))
37 |
38 | # 添加反面的散点
39 | scatter_fig.add_trace(go.Scatter(
40 | x=iteration[toss.flatten() == 0],
41 | y=toss[toss == 0].flatten(),
42 | mode='markers',
43 | marker=dict(color='blue', size=6),
44 | name='Tail (0)'
45 | ))
46 |
47 | # 设置图表布局
48 | scatter_fig.update_layout(
49 | title='Coin Toss Results',
50 | xaxis_title='Iteration',
51 | yaxis_title='Result (0: Tail, 1: Head)',
52 | yaxis=dict(tickvals=[0, 1]),
53 | showlegend=True
54 | )
55 |
56 | # 创建第二幅图:累积均值折线图
57 | mean_fig = go.Figure()
58 |
59 | # 添加累积均值曲线
60 | mean_fig.add_trace(go.Scatter(
61 | x=iteration,
62 | y=cum_mean,
63 | mode='lines',
64 | line=dict(color='green'),
65 | name='Cumulative Mean'
66 | ))
67 |
68 | # 添加水平线 y=0.5
69 | mean_fig.add_trace(go.Scatter(
70 | x=[1, num_toss],
71 | y=[0.5, 0.5],
72 | mode='lines',
73 | line=dict(color='red', dash='dash'),
74 | name='Mean = 0.5'
75 | ))
76 |
77 | # 设置图表布局
78 | mean_fig.update_layout(
79 | title='Cumulative Mean of Coin Toss',
80 | xaxis_title='Iteration',
81 | yaxis_title='Cumulative Mean',
82 | yaxis=dict(tickvals=[0, 0.5, 1]),
83 | showlegend=True
84 | )
85 |
86 | # 在 Streamlit 中展示图表
87 | st.plotly_chart(scatter_fig) # 显示抛硬币结果图
88 | st.plotly_chart(mean_fig) # 显示累积均值图
89 |
--------------------------------------------------------------------------------
/Book3_Ch20_概率入门__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch20_概率入门__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch21_Python_Codes/Streamlit_Bk3_Ch21_01.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | ## 导入必要的库
9 | import streamlit as st # 导入Streamlit库,用于创建交互式Web应用
10 | import plotly.express as px # 导入Plotly库中的express模块,用于数据可视化
11 |
12 | ## 加载鸢尾花数据集
13 | df = px.data.iris() # 使用Plotly内置的函数加载鸢尾花数据集
14 |
15 | ## 从数据集中提取特征列名
16 | features = df.columns.to_list()[:-2] # 获取数据集的前四列作为特征名称列表
17 |
18 | ## 在侧边栏中创建交互式控件
19 | with st.sidebar: # 创建Streamlit的侧边栏
20 | st.write('2D scatter plot') # 显示侧边栏的标题
21 |
22 | x_feature = st.radio('Horizontal axis', # 创建单选按钮选择水平轴的特征
23 | features)
24 |
25 | y_feature = st.radio('Vertical axis', # 创建单选按钮选择垂直轴的特征
26 | features)
27 |
28 | marginal_x = st.radio('Horizontal marginal', # 创建单选按钮选择水平轴的边际分布类型
29 | ["histogram",
30 | "rug",
31 | "box",
32 | "violin"])
33 |
34 | marginal_y = st.radio('Vertical marginal', # 创建单选按钮选择垂直轴的边际分布类型
35 | ["histogram",
36 | "rug",
37 | "box",
38 | "violin"])
39 |
40 | ## 展示原始数据部分
41 | with st.expander('Original data'): # 创建一个可折叠部分,标题为"Original data"
42 | st.write(df) # 在可折叠部分中显示鸢尾花数据集
43 |
44 | ## 绘制二维散点图部分
45 | with st.expander('2D scatter plot'): # 创建一个可折叠部分,标题为"2D scatter plot"
46 |
47 | fig_2 = px.scatter(df, # 使用Plotly的散点图绘制函数
48 | x=x_feature, # 设置x轴的特征
49 | y=y_feature, # 设置y轴的特征
50 | color="species", # 根据物种类别进行颜色分组
51 | marginal_x=marginal_x, # 设置水平边际分布类型
52 | marginal_y=marginal_y) # 设置垂直边际分布类型
53 |
54 | st.plotly_chart(fig_2) # 在Streamlit应用中显示生成的散点图
55 |
--------------------------------------------------------------------------------
/Book3_Ch21_统计入门__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch21_统计入门__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch22_Python_Codes/Bk3_Ch22_03.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 22\n",
9 | "\n",
10 | "# 向量夹角\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "abc1dff6-2af1-4b1d-849d-d4f95e7f1688",
17 | "metadata": {},
18 | "source": [
19 | "这段代码通过向量的点积公式来计算两个向量 $ \\vec{a} = [4, 1] $ 和 $ \\vec{b} = [1, 3] $ 之间的夹角。首先,代码计算了向量 $ \\vec{a} $ 和 $ \\vec{b} $ 的 $L2$ 范数,分别表示为 $||\\vec{a}||$ 和 $||\\vec{b}||$,即:\n",
20 | "\n",
21 | "$$\n",
22 | "||\\vec{a}|| = \\sqrt{4^2 + 1^2} = \\sqrt{17}\n",
23 | "$$\n",
24 | "\n",
25 | "$$\n",
26 | "||\\vec{b}|| = \\sqrt{1^2 + 3^2} = \\sqrt{10}\n",
27 | "$$\n",
28 | "\n",
29 | "接着,计算两向量的点积 $ \\vec{a} \\cdot \\vec{b} $:\n",
30 | "\n",
31 | "$$\n",
32 | "\\vec{a} \\cdot \\vec{b} = 4 \\cdot 1 + 1 \\cdot 3 = 4 + 3 = 7\n",
33 | "$$\n",
34 | "\n",
35 | "根据点积的定义,余弦值可以表示为:\n",
36 | "\n",
37 | "$$\n",
38 | "\\cos \\theta = \\frac{\\vec{a} \\cdot \\vec{b}}{||\\vec{a}|| \\cdot ||\\vec{b}||}\n",
39 | "$$\n",
40 | "\n",
41 | "代入已知数值得到:\n",
42 | "\n",
43 | "$$\n",
44 | "\\cos \\theta = \\frac{7}{\\sqrt{17} \\cdot \\sqrt{10}}\n",
45 | "$$\n",
46 | "\n",
47 | "最后,代码通过反余弦函数计算出夹角 $\\theta$ 的弧度值,并将其转换为角度。结果就是两个向量之间的角度,用度数表示。"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": 1,
53 | "id": "247d6d2b-312e-4d1e-a86f-0b3a849c98e3",
54 | "metadata": {},
55 | "outputs": [],
56 | "source": [
57 | "import numpy as np"
58 | ]
59 | },
60 | {
61 | "cell_type": "markdown",
62 | "id": "95e598b2-6a7a-44f2-8638-ad223e81528e",
63 | "metadata": {},
64 | "source": [
65 | "## 定义向量"
66 | ]
67 | },
68 | {
69 | "cell_type": "code",
70 | "execution_count": 2,
71 | "id": "9793e936-6ebd-4ce9-a355-f3aea835f56d",
72 | "metadata": {},
73 | "outputs": [],
74 | "source": [
75 | "a = [4, 1] # 向量 a\n",
76 | "b = [1, 3] # 向量 b"
77 | ]
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "id": "dc64fb3a-43d9-4bd9-99ba-f2ca3180e0eb",
82 | "metadata": {},
83 | "source": [
84 | "## 计算 L2 范数(向量长度)"
85 | ]
86 | },
87 | {
88 | "cell_type": "code",
89 | "execution_count": 3,
90 | "id": "1019e4e4-352f-4af1-8b01-28ac3b9d0eaf",
91 | "metadata": {},
92 | "outputs": [],
93 | "source": [
94 | "a_norm = np.linalg.norm(a) # 计算向量 a 的 L2 范数\n",
95 | "b_norm = np.linalg.norm(b) # 计算向量 b 的 L2 范数"
96 | ]
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "id": "f86aff56-6d9e-412c-86ef-1ea269882af3",
101 | "metadata": {},
102 | "source": [
103 | "## 计算点积"
104 | ]
105 | },
106 | {
107 | "cell_type": "code",
108 | "execution_count": 4,
109 | "id": "3adf24b8-a250-4cc5-8f33-346ab7a50a3b",
110 | "metadata": {},
111 | "outputs": [],
112 | "source": [
113 | "a_dot_b = np.dot(a, b) # 计算向量 a 和向量 b 的点积"
114 | ]
115 | },
116 | {
117 | "cell_type": "markdown",
118 | "id": "6fadfc35-8183-430e-a628-890bd64b9dc2",
119 | "metadata": {},
120 | "source": [
121 | "## 计算余弦值"
122 | ]
123 | },
124 | {
125 | "cell_type": "code",
126 | "execution_count": 5,
127 | "id": "1cf2dbd2-8b96-43b2-b4dd-503167cd39fb",
128 | "metadata": {},
129 | "outputs": [],
130 | "source": [
131 | "cos_result = a_dot_b / a_norm / b_norm # 计算余弦值"
132 | ]
133 | },
134 | {
135 | "cell_type": "markdown",
136 | "id": "0d93e3ac-046d-4a21-8cec-8205759a234c",
137 | "metadata": {},
138 | "source": [
139 | "## 弧度转角度"
140 | ]
141 | },
142 | {
143 | "cell_type": "code",
144 | "execution_count": 6,
145 | "id": "748a379a-c3ff-4ffd-868c-6390362cd758",
146 | "metadata": {},
147 | "outputs": [
148 | {
149 | "name": "stdout",
150 | "output_type": "stream",
151 | "text": [
152 | "57.52880770915151\n"
153 | ]
154 | }
155 | ],
156 | "source": [
157 | "angle = np.degrees(np.arccos(cos_result)) # 将弧度转换为角度\n",
158 | "print(angle) # 打印角度结果"
159 | ]
160 | },
161 | {
162 | "cell_type": "code",
163 | "execution_count": null,
164 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
165 | "metadata": {},
166 | "outputs": [],
167 | "source": []
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": null,
172 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
173 | "metadata": {},
174 | "outputs": [],
175 | "source": []
176 | }
177 | ],
178 | "metadata": {
179 | "kernelspec": {
180 | "display_name": "Python 3 (ipykernel)",
181 | "language": "python",
182 | "name": "python3"
183 | },
184 | "language_info": {
185 | "codemirror_mode": {
186 | "name": "ipython",
187 | "version": 3
188 | },
189 | "file_extension": ".py",
190 | "mimetype": "text/x-python",
191 | "name": "python",
192 | "nbconvert_exporter": "python",
193 | "pygments_lexer": "ipython3",
194 | "version": "3.12.7"
195 | }
196 | },
197 | "nbformat": 4,
198 | "nbformat_minor": 5
199 | }
200 |
--------------------------------------------------------------------------------
/Book3_Ch22_向量__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch22_向量__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch23_Python_Codes/Bk3_Ch23_01.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 23\n",
9 | "\n",
10 | "# 求解线性方程\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "d17de955-9c02-4f23-bec2-48dfdbddcb7f",
17 | "metadata": {},
18 | "source": [
19 | "这段代码通过不同的方法求解了一个线性方程组$Ax = b$,其中矩阵$A = \\begin{bmatrix} 1 & 1 \\\\ 2 & 4 \\end{bmatrix}$,向量$b = \\begin{bmatrix} 35 \\\\ 94 \\end{bmatrix}$。具体来说,代码依次使用矩阵求逆、直接解法和符号求解三种方式来得到解$x$。\n",
20 | "\n",
21 | "1. **矩阵求逆法**:首先计算矩阵$A$的逆矩阵$A^{-1}$,然后通过矩阵乘法$x = A^{-1}b$得到解$x$。这是基于线性方程组的一般解法$x = A^{-1}b$。\n",
22 | " \n",
23 | "2. **NumPy的直接解法**:使用NumPy中的`solve`函数求解该线性方程组。该函数内部优化了求解过程,通常比求逆计算更为高效。\n",
24 | "\n",
25 | "3. **符号求解**:接着引入SymPy库,通过符号变量$x_1$和$x_2$构建方程$x_1 + x_2 = 35$和$2x_1 + 4x_2 = 94$。SymPy的`solve`函数求得每个变量的解,并以字典形式输出。\n",
26 | "\n",
27 | "4. **线性方程组求解集**:最后,使用SymPy的`linsolve`函数求解方程组。该函数返回一个包含解的集合形式,适用于线性方程组的求解。\n",
28 | "\n",
29 | "综上,代码验证了方程组$x_1 + x_2 = 35$和$2x_1 + 4x_2 = 94$的解,通过数值方法和符号方法都得到相同的解$x = \\begin{bmatrix} 23 \\\\ 12 \\end{bmatrix}$。"
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": 1,
35 | "id": "c878bdb8-7303-4c06-b240-364b23d218c6",
36 | "metadata": {},
37 | "outputs": [],
38 | "source": [
39 | "import numpy as np"
40 | ]
41 | },
42 | {
43 | "cell_type": "markdown",
44 | "id": "43132808-16e6-407c-be98-80e247ccae75",
45 | "metadata": {},
46 | "source": [
47 | "## 定义矩阵A和向量b"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": 2,
53 | "id": "c7c1f3d4-8cb0-4af5-a4a4-1c004a00dd48",
54 | "metadata": {},
55 | "outputs": [],
56 | "source": [
57 | "A = np.array([[1,1], # 系数矩阵\n",
58 | " [2,4]])"
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": 3,
64 | "id": "9db9cdf1-e747-4e5e-be24-50147d6b9e8c",
65 | "metadata": {},
66 | "outputs": [],
67 | "source": [
68 | "b = np.array([[35], # 常数项向量\n",
69 | " [94]])"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "id": "0b74f5ab-eae6-4eff-8814-b5c34dd9c18e",
75 | "metadata": {},
76 | "source": [
77 | "## 通过矩阵的逆求解方程组"
78 | ]
79 | },
80 | {
81 | "cell_type": "code",
82 | "execution_count": 4,
83 | "id": "e1f20913-4913-4363-9a58-5173786cb371",
84 | "metadata": {},
85 | "outputs": [],
86 | "source": [
87 | "A_inv = np.linalg.inv(A) # 计算矩阵A的逆"
88 | ]
89 | },
90 | {
91 | "cell_type": "code",
92 | "execution_count": 5,
93 | "id": "4a633470-ee4f-49b5-9827-3afa802b087e",
94 | "metadata": {},
95 | "outputs": [
96 | {
97 | "name": "stdout",
98 | "output_type": "stream",
99 | "text": [
100 | "[[23.]\n",
101 | " [12.]]\n"
102 | ]
103 | }
104 | ],
105 | "source": [
106 | "x = A_inv@b # 计算解向量x\n",
107 | "print(x) # 输出解向量"
108 | ]
109 | },
110 | {
111 | "cell_type": "markdown",
112 | "id": "ecda8f48-03bb-41ac-88bb-b45cfeaadc9f",
113 | "metadata": {},
114 | "source": [
115 | "## 使用NumPy中的solve函数求解方程组"
116 | ]
117 | },
118 | {
119 | "cell_type": "code",
120 | "execution_count": 6,
121 | "id": "8b6520bf-249b-4aa0-a547-b8f1220a9c53",
122 | "metadata": {},
123 | "outputs": [
124 | {
125 | "name": "stdout",
126 | "output_type": "stream",
127 | "text": [
128 | "[[23.]\n",
129 | " [12.]]\n"
130 | ]
131 | }
132 | ],
133 | "source": [
134 | "x_ = np.linalg.solve(A,b) # 使用solve直接求解\n",
135 | "print(x_) # 输出解向量"
136 | ]
137 | },
138 | {
139 | "cell_type": "markdown",
140 | "id": "53e0da88-aecd-4508-9d06-a942f9ad6db2",
141 | "metadata": {},
142 | "source": [
143 | "## 使用SymPy符号计算解"
144 | ]
145 | },
146 | {
147 | "cell_type": "code",
148 | "execution_count": 7,
149 | "id": "da4fdff4-02d1-47d7-9e9a-7c4305f3c7d5",
150 | "metadata": {},
151 | "outputs": [],
152 | "source": [
153 | "from sympy import *\n",
154 | "x1, x2 = symbols(['x1', 'x2']) # 定义符号变量x1, x2"
155 | ]
156 | },
157 | {
158 | "cell_type": "code",
159 | "execution_count": 8,
160 | "id": "cedde266-0648-4d6d-a3c7-4417fd37aa14",
161 | "metadata": {},
162 | "outputs": [
163 | {
164 | "name": "stdout",
165 | "output_type": "stream",
166 | "text": [
167 | "{x1: 23, x2: 12}\n"
168 | ]
169 | }
170 | ],
171 | "source": [
172 | "sol = solve([x1 + x2 - 35, 2*x1 + 4*x2 - 94], [x1, x2]) # 使用solve求解方程组\n",
173 | "print(sol) # 输出解的字典形式"
174 | ]
175 | },
176 | {
177 | "cell_type": "markdown",
178 | "id": "3077383a-a387-4f61-809a-3d68ba7e3d2a",
179 | "metadata": {},
180 | "source": [
181 | "## 使用linsolve求解线性方程组"
182 | ]
183 | },
184 | {
185 | "cell_type": "code",
186 | "execution_count": 9,
187 | "id": "f1c6d415-70f7-4e1d-8385-bcd72ef176f3",
188 | "metadata": {},
189 | "outputs": [
190 | {
191 | "name": "stdout",
192 | "output_type": "stream",
193 | "text": [
194 | "{(23, 12)}\n"
195 | ]
196 | }
197 | ],
198 | "source": [
199 | "from sympy.solvers.solveset import linsolve\n",
200 | "sol_ = linsolve([x1 + x2 - 35, 2*x1 + 4*x2 - 94], [x1, x2]) # 使用linsolve求解\n",
201 | "print(sol_) # 输出解的集合形式"
202 | ]
203 | },
204 | {
205 | "cell_type": "code",
206 | "execution_count": null,
207 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
208 | "metadata": {},
209 | "outputs": [],
210 | "source": []
211 | },
212 | {
213 | "cell_type": "code",
214 | "execution_count": null,
215 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
216 | "metadata": {},
217 | "outputs": [],
218 | "source": []
219 | }
220 | ],
221 | "metadata": {
222 | "kernelspec": {
223 | "display_name": "Python 3 (ipykernel)",
224 | "language": "python",
225 | "name": "python3"
226 | },
227 | "language_info": {
228 | "codemirror_mode": {
229 | "name": "ipython",
230 | "version": 3
231 | },
232 | "file_extension": ".py",
233 | "mimetype": "text/x-python",
234 | "name": "python",
235 | "nbconvert_exporter": "python",
236 | "pygments_lexer": "ipython3",
237 | "version": "3.12.7"
238 | }
239 | },
240 | "nbformat": 4,
241 | "nbformat_minor": 5
242 | }
243 |
--------------------------------------------------------------------------------
/Book3_Ch23_Python_Codes/Bk3_Ch23_04.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827",
6 | "metadata": {},
7 | "source": [
8 | "Chapter 23\n",
9 | "\n",
10 | "# 矩阵伪逆\n",
11 | "Book_3《数学要素》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "id": "7171e532-c1b9-4020-af77-97a6d1672617",
17 | "metadata": {},
18 | "source": [
19 | "这段代码的目的是通过最小二乘法求解线性方程组,从而找到一个最佳的参数估计。给定矩阵 $A$ 和向量 $b$,我们希望找到一个向量 $x$ 使得 $Ax \\approx b$,即使得 $Ax$ 与 $b$ 的差异最小。\n",
20 | "\n",
21 | "首先,我们定义了一个矩阵 $A$,其包含了数据的特征或自变量,以及一个向量 $b$,它包含了对应的观测值或因变量。然后,我们使用最小二乘法的公式来计算参数向量 $x$:\n",
22 | "\n",
23 | "$$\n",
24 | "x = (A^T A)^{-1} A^T b\n",
25 | "$$\n",
26 | "\n",
27 | "这里,$A^T$ 是 $A$ 的转置,$A^T A$ 是 $A$ 的自乘矩阵,通常称为设计矩阵。我们首先计算 $A^T A$,然后求其逆,接着用它乘以 $A^T$ 和 $b$,最终得到参数向量 $x$。\n",
28 | "\n",
29 | "这个过程可以看作是最小化平方误差的优化问题。我们的目标是最小化以下目标函数:\n",
30 | "\n",
31 | "$$\n",
32 | "\\text{minimize} \\quad ||Ax - b||^2\n",
33 | "$$\n",
34 | "\n",
35 | "通过求解这个优化问题,我们可以找到最佳的线性组合参数,从而使得模型的预测值 $Ax$ 尽可能接近观测值 $b$。\n",
36 | "\n",
37 | "最后,程序输出计算得到的 $x$ 值,即最佳的参数估计。这些参数可以用来进一步分析或进行预测。"
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": 1,
43 | "id": "44ef8b02-c4e2-4d39-bb00-1fe9166b02d4",
44 | "metadata": {},
45 | "outputs": [],
46 | "source": [
47 | "import numpy as np"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": 2,
53 | "id": "d2a498a9-8d90-41ab-8cca-b6f8a47c0111",
54 | "metadata": {},
55 | "outputs": [],
56 | "source": [
57 | "A = np.array([[1,1], # 定义矩阵A\n",
58 | " [1,1],\n",
59 | " [2,4],\n",
60 | " [2,4]])"
61 | ]
62 | },
63 | {
64 | "cell_type": "code",
65 | "execution_count": 3,
66 | "id": "6616eaae-4422-4563-a5a9-741176e042d2",
67 | "metadata": {},
68 | "outputs": [],
69 | "source": [
70 | "b = np.array([[30], # 定义矩阵b\n",
71 | " [35],\n",
72 | " [90],\n",
73 | " [110]])"
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": 4,
79 | "id": "43a3e18e-676d-4ff7-a47a-7d395490a9d4",
80 | "metadata": {},
81 | "outputs": [],
82 | "source": [
83 | "x = np.linalg.inv(A.T@A)@A.T@b # 计算线性方程的最小二乘解"
84 | ]
85 | },
86 | {
87 | "cell_type": "code",
88 | "execution_count": 5,
89 | "id": "ecd518a4-820f-44ea-9e8f-baad55ee08d8",
90 | "metadata": {},
91 | "outputs": [
92 | {
93 | "name": "stdout",
94 | "output_type": "stream",
95 | "text": [
96 | "[[15. ]\n",
97 | " [17.5]]\n"
98 | ]
99 | }
100 | ],
101 | "source": [
102 | "print(x) # 输出结果"
103 | ]
104 | },
105 | {
106 | "cell_type": "code",
107 | "execution_count": null,
108 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
109 | "metadata": {},
110 | "outputs": [],
111 | "source": []
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": null,
116 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
117 | "metadata": {},
118 | "outputs": [],
119 | "source": []
120 | }
121 | ],
122 | "metadata": {
123 | "kernelspec": {
124 | "display_name": "Python 3 (ipykernel)",
125 | "language": "python",
126 | "name": "python3"
127 | },
128 | "language_info": {
129 | "codemirror_mode": {
130 | "name": "ipython",
131 | "version": 3
132 | },
133 | "file_extension": ".py",
134 | "mimetype": "text/x-python",
135 | "name": "python",
136 | "nbconvert_exporter": "python",
137 | "pygments_lexer": "ipython3",
138 | "version": "3.12.7"
139 | }
140 | },
141 | "nbformat": 4,
142 | "nbformat_minor": 5
143 | }
144 |
--------------------------------------------------------------------------------
/Book3_Ch23_Python_Codes/Streamlit_Bk3_Ch23_02.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | ## 导入必要的库
9 | import numpy as np # 导入NumPy库,用于数值计算
10 | import matplotlib.pyplot as plt # 导入Matplotlib库,用于绘图
11 | import streamlit as st # 导入Streamlit库,用于创建交互式应用
12 |
13 | ## 定义一个函数,用于绘制向量
14 | def draw_vector(vector, RBG): # 自定义函数,用于绘制向量
15 | array = np.array([[0, 0, vector[0], vector[1]]], dtype=object) # 创建一个二维向量的数组
16 | X, Y, U, V = zip(*array) # 解压向量的坐标
17 | plt.quiver(X, Y, U, V, angles='xy', scale_units='xy', scale=1, color=RBG) # 使用quiver函数绘制向量
18 |
19 | ## 创建网格数据
20 | x1 = np.arange(-25, 25 + 1, step=1) # 生成x1的值范围,范围为-25到25,步长为1
21 | x2 = np.arange(-25, 25 + 1, step=1) # 生成x2的值范围,范围为-25到25,步长为1
22 | XX1, XX2 = np.meshgrid(x1, x2) # 创建网格点的x和y坐标
23 | X = np.column_stack((XX1.ravel(), XX2.ravel())) # 将网格点展开为二维数组
24 |
25 | ## 在侧边栏设置交互参数
26 | with st.sidebar: # 创建Streamlit侧边栏
27 | st.latex(r'''A = \begin{bmatrix}
28 | a & b\\
29 | c & d
30 | \end{bmatrix}''') # 显示矩阵A的LaTeX公式
31 |
32 | a = st.slider('a', -2.0, 2.0, step=0.1, value=1.0) # 创建滑块,用于调整矩阵A中a的值
33 | b = st.slider('b', -2.0, 2.0, step=0.1, value=0.0) # 创建滑块,用于调整矩阵A中b的值
34 | c = st.slider('c', -2.0, 2.0, step=0.1, value=0.0) # 创建滑块,用于调整矩阵A中c的值
35 | d = st.slider('d', -2.0, 2.0, step=0.1, value=1.0) # 创建滑块,用于调整矩阵A中d的值
36 |
37 | ## 定义变换矩阵A
38 | theta = np.pi / 6 # 定义旋转角度
39 | A = np.array([[a, b], # 构造矩阵A,使用侧边栏中定义的a、b、c、d的值
40 | [c, d]], dtype=float)
41 |
42 | ## 计算变换后的网格点
43 | Z = X @ A.T # 使用矩阵A对网格点X进行变换
44 | ZZ1 = Z[:, 0].reshape((len(x1), len(x2))) # 提取变换后网格的x坐标
45 | ZZ2 = Z[:, 1].reshape((len(x1), len(x2))) # 提取变换后网格的y坐标
46 |
47 | ## 绘制原始基底图形
48 | fig_1, ax = plt.subplots() # 创建一个图形和坐标轴
49 | ## 设置背景透明
50 | fig_1.patch.set_alpha(0) # 设置整个图形背景为透明
51 | ax.set_facecolor('none') # 设置坐标轴背景为透明
52 | plt.plot(XX1, XX2, color=[0.2, 0.8, 0.8]) # 绘制网格线
53 | plt.plot(XX1.T, XX2.T, color=[0.8, 0.8, 0.2]) # 绘制网格线的转置
54 | plt.axis('scaled') # 设置坐标轴比例
55 | ax.set_xlim([0, 8]) # 设置x轴范围
56 | ax.set_ylim([0, 8]) # 设置y轴范围
57 | plt.xticks(np.arange(0, 8 + 1, step=2)) # 设置x轴刻度
58 | plt.yticks(np.arange(0, 8 + 1, step=2)) # 设置y轴刻度
59 | ax.spines['top'].set_visible(False) # 隐藏上边框
60 | ax.spines['right'].set_visible(False) # 隐藏右边框
61 |
62 | ## 绘制变换后的基底图形
63 | fig_2, ax = plt.subplots() # 创建一个图形和坐标轴
64 | ## 设置背景透明
65 | fig_2.patch.set_alpha(0) # 设置整个图形背景为透明
66 | ax.set_facecolor('none') # 设置坐标轴背景为透明
67 | plt.plot(ZZ1, ZZ2, color=[0.2, 0.8, 0.8]) # 绘制变换后的网格线
68 | plt.plot(ZZ1.T, ZZ2.T, color=[0.8, 0.8, 0.2]) # 绘制变换后的网格线的转置
69 | plt.axis('scaled') # 设置坐标轴比例
70 | ax.set_xlim([0, 8]) # 设置x轴范围
71 | ax.set_ylim([0, 8]) # 设置y轴范围
72 | plt.xticks(np.arange(0, 8 + 1, step=2)) # 设置x轴刻度
73 | plt.yticks(np.arange(0, 8 + 1, step=2)) # 设置y轴刻度
74 | ax.spines['top'].set_visible(False) # 隐藏上边框
75 | ax.spines['right'].set_visible(False) # 隐藏右边框
76 |
77 | ## 在Streamlit中展示两个图形
78 | col1, col2 = st.columns(2) # 创建两个列容器
79 | with col1: # 在第一列展示原始基底图形
80 | st.pyplot(fig_1)
81 | with col2: # 在第二列展示变换后的基底图形
82 | st.pyplot(fig_2)
83 |
--------------------------------------------------------------------------------
/Book3_Ch23_鸡兔同笼1__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch23_鸡兔同笼1__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch24_Python_Codes/Streamlit_Bk3_Ch24_02.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | ## 导入必要的库
9 | import numpy as np # 导入NumPy库,用于数值计算
10 | import streamlit as st # 导入Streamlit库,用于交互式展示
11 | import plotly.express as px # 导入Plotly Express库,用于绘制交互式图表
12 | import pandas as pd # 导入Pandas库,用于数据处理
13 | import plotly.graph_objects as go # 导入Plotly图形对象库,用于添加自定义图层
14 |
15 | ## 定义鸡和兔的数据
16 | num_chickens = np.array([32, 110, 71, 79, 45, 20, 56, 55, 87, 68, 87, 63, 31, 88]) # 鸡的数量数据
17 | num_rabbits = np.array([22, 53, 39, 40, 25, 15, 34, 34, 52, 41, 43, 33, 24, 52]) # 兔的数量数据
18 |
19 | ## 创建一个DataFrame,用于可视化
20 | df = pd.DataFrame(np.vstack((num_chickens, num_rabbits)).T, # 将鸡和兔的数据堆叠并转置
21 | columns=['num_chickens', 'num_rabbits']) # 设置列名为鸡的数量和兔的数量
22 |
23 | ## 在侧边栏设置交互式参数
24 | with st.sidebar: # 创建侧边栏
25 | st.latex('\hat{y} = ax + b') # 显示线性回归公式
26 | a = st.slider('a, slope:', # 滑块,用于选择斜率a
27 | min_value=0.05, # 设置斜率的最小值为0.05
28 | max_value=1.0, # 设置斜率的最大值为1.0
29 | step=0.01) # 每次调整的步长为0.01
30 | b = st.slider('b, intercept:', # 滑块,用于选择截距b
31 | min_value=0.0, # 设置截距的最小值为0.0
32 | max_value=10.0, # 设置截距的最大值为10.0
33 | step=0.1) # 每次调整的步长为0.1
34 |
35 | ## 计算预测值和误差
36 | y_hat = a * num_chickens + b # 根据选定的斜率和截距计算预测值
37 | SSE = np.sum((num_rabbits - y_hat) ** 2) # 计算平方误差的总和
38 |
39 | ## 在Streamlit中显示误差
40 | st.write('Sum of squared errors (SSE): %.2f' % SSE) # 在页面显示平方误差
41 |
42 | ## 绘制散点图和回归线
43 | fig = px.scatter(df, x="num_chickens", y="num_rabbits", trendline="ols") # 使用Plotly绘制散点图和OLS回归线
44 |
45 | ## 添加预测值的自定义图层
46 | fig.add_trace(go.Scatter(x=num_chickens, y=y_hat, # 添加预测值的散点
47 | name='Predicted', # 设置图例名称
48 | line=dict(color='red', width=1))) # 设置预测线的颜色和宽度
49 |
50 | ## 在Streamlit中展示图形
51 | st.plotly_chart(fig) # 将绘制的图形嵌入到Streamlit页面
52 |
--------------------------------------------------------------------------------
/Book3_Ch24_鸡兔同笼2__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch24_鸡兔同笼2__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/Book3_Ch25_Python_Codes/Streamlit_Bk3_Ch25_02.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | ## 导入必要的库
9 | import numpy as np # 导入NumPy库,用于矩阵计算
10 | import streamlit as st # 导入Streamlit库,用于交互式展示
11 | import plotly.express as px # 导入Plotly库,用于创建交互式图表
12 |
13 | ## 定义将矩阵转换为LaTeX格式的函数
14 | def bmatrix(a): # 自定义函数,用于生成LaTeX格式的bmatrix
15 | if len(a.shape) > 2: # 检查输入矩阵是否超过二维
16 | raise ValueError('bmatrix can at most display two dimensions') # 抛出错误提示
17 | lines = str(a).replace('[', '').replace(']', '').splitlines() # 将矩阵转换为字符串并按行分割
18 | rv = [r'\begin{bmatrix}'] # 添加LaTeX起始语法
19 | rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines] # 按行格式化为LaTeX矩阵格式
20 | rv += [r'\end{bmatrix}'] # 添加LaTeX结束语法
21 | return '\n'.join(rv) # 返回拼接后的字符串
22 |
23 | ## 定义转移矩阵T
24 | T = np.matrix([[0.7, 0.2], # 第一行表示从状态1到状态1和状态2的转移概率
25 | [0.3, 0.8]]) # 第二行表示从状态2到状态1和状态2的转移概率
26 |
27 | ## 在侧边栏设置交互式组件
28 | with st.sidebar: # 创建Streamlit侧边栏
29 | p = st.slider('Ratio of chickens: ', # 滑块,用于选择初始鸡的比例
30 | min_value=0.0, # 最小值为0
31 | max_value=1.0, # 最大值为1
32 | step=0.05) # 每次变化的步长为0.05
33 |
34 | num_steps = st.slider('Number of nights: ', # 滑块,用于选择时间步数
35 | min_value=10, # 最小值为10
36 | max_value=30, # 最大值为30
37 | step=1) # 每次变化的步长为1
38 |
39 | pi_0 = np.array([[p], # 根据选择的鸡的比例生成初始状态向量
40 | [1-p]]) # 兔的比例为1减去鸡的比例
41 |
42 | st.latex('T = ' + bmatrix(T)) # 在侧边栏显示转移矩阵的LaTeX格式
43 | st.latex('\pi (0) = ' + bmatrix(pi_0)) # 显示初始状态向量的LaTeX格式
44 | st.latex('\pi(k + 1) = T \pi(k)') # 显示状态转移公式的LaTeX格式
45 |
46 | ## 初始化状态向量数组
47 | pi_array = pi_0 # 初始化状态向量数组为初始状态向量
48 | pi_idx = pi_0 # 设置当前状态向量为初始状态向量
49 |
50 | ## 计算多个时间步的状态转移
51 | for idx in np.arange(0, num_steps): # 遍历每个时间步
52 | pi_idx = T @ pi_idx # 使用转移矩阵更新当前状态向量
53 | pi_array = np.column_stack((pi_array, pi_idx)) # 将当前状态向量添加到状态向量数组中
54 |
55 | ## 可视化状态向量的转移
56 | fig = px.imshow(pi_array, text_auto=True, # 使用Plotly生成状态向量的热力图
57 | color_continuous_scale='RdYlBu_r') # 设置颜色映射为红-黄-蓝渐变
58 |
59 | fig.update_layout( # 更新图表布局
60 | autosize=False, # 禁用自动调整大小
61 | width=1000, # 设置图表宽度为1000
62 | height=500, # 设置图表高度为500
63 | coloraxis_showscale=False) # 隐藏颜色条
64 |
65 | st.plotly_chart(fig) # 在Streamlit中显示图表
66 |
--------------------------------------------------------------------------------
/Book3_Ch25_Python_Codes/Streamlit_Bk3_Ch25_03.py:
--------------------------------------------------------------------------------
1 | ###############
2 | # Authored by Weisheng Jiang
3 | # Book 3 | From Basic Arithmetic to Machine Learning
4 | # Published and copyrighted by Tsinghua University Press
5 | # Beijing, China, 2025
6 | ###############
7 |
8 | ## 导入必要的库
9 | import numpy as np # 导入NumPy库,用于矩阵和数组计算
10 | import seaborn as sns # 导入Seaborn库,用于可视化
11 | import matplotlib.pyplot as plt # 导入Matplotlib库,用于绘图
12 | import streamlit as st # 导入Streamlit库,用于交互式展示
13 |
14 | ## 定义绘制向量的函数
15 | def draw_vector(vector, RBG, ax): # 自定义函数,用于绘制二维向量
16 | ax.quiver(0, 0, vector[0], vector[1], # 绘制从原点到指定点的向量
17 | angles='xy', # 设置为笛卡尔坐标系
18 | scale_units='xy', # 使用笛卡尔单位
19 | scale=1, # 设置比例为1,表示实际大小
20 | color=RBG) # 设置向量颜色
21 |
22 | ## 定义转移矩阵
23 | T = np.matrix([[0.7, 0.2], # 定义转移矩阵T,第一行表示从状态1到状态1和状态2的转移概率
24 | [0.3, 0.8]]) # 第二行表示从状态2到状态1和状态2的转移概率
25 |
26 | ## 定义LaTeX格式化函数
27 | def bmatrix(a): # 自定义函数,用于将矩阵转换为LaTeX的bmatrix格式
28 | if len(a.shape) > 2: # 检查矩阵的维度是否大于2
29 | raise ValueError('bmatrix can at most display two dimensions') # 如果维度大于2,抛出错误
30 | lines = str(a).replace('[', '').replace(']', '').splitlines() # 将矩阵转为字符串并分行处理
31 | rv = [r'\begin{bmatrix}'] # 添加LaTeX起始语法
32 | rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines] # 按行拼接LaTeX矩阵格式
33 | rv += [r'\end{bmatrix}'] # 添加LaTeX结束语法
34 | return '\n'.join(rv) # 返回拼接后的字符串
35 |
36 | ## 定义初始状态向量和交互式组件
37 | with st.sidebar: # 创建Streamlit侧边栏
38 | p = st.slider('Ratio of chickens: ', # 滑块,用于选择鸡的初始比例
39 | min_value=0.0, # 最小值为0
40 | max_value=1.0, # 最大值为1
41 | step=0.05) # 步长为0.05
42 |
43 | num_steps = st.slider('Number of nights: ', # 滑块,用于选择时间步数
44 | min_value=10, # 最小值为10
45 | max_value=20, # 最大值为20
46 | step=1) # 步长为1
47 |
48 | pi_0 = np.array([[p], # 根据选择的鸡的比例计算初始状态向量
49 | [1-p]]) # 兔的比例为1减去鸡的比例
50 |
51 | st.latex('T = ' + bmatrix(T)) # 显示转移矩阵T的LaTeX格式
52 | st.latex('\pi (0) = ' + bmatrix(pi_0)) # 显示初始状态向量的LaTeX格式
53 | st.latex('\pi(k + 1) = T \pi(k)') # 显示状态转移公式的LaTeX格式
54 |
55 | ## 创建单位圆的网格和模长计算
56 | x1 = np.linspace(-1.1, 1.1, num=201) # 定义x轴的取值范围
57 | x2 = x1 # 定义y轴的取值范围,与x轴相同
58 | xx1, xx2 = np.meshgrid(x1, x2) # 生成二维网格
59 | zz = ((np.abs((xx1))**2) + (np.abs((xx2))**2))**(1./2) # 计算网格中每点的模长
60 |
61 | ## 初始化状态向量
62 | pi = pi_0 # 设置初始状态向量为用户选择的初始值
63 |
64 | ## 定义颜色渐变
65 | colors = plt.cm.rainbow(np.linspace(0, 1, num_steps + 1)) # 为每个时间步生成颜色
66 |
67 | ## 创建图形
68 | fig, ax = plt.subplots(figsize=(10, 10)) # 创建图形和坐标轴
69 |
70 | ## 设置背景透明
71 | fig.patch.set_alpha(0) # 设置整个图形背景为透明
72 | ax.set_facecolor('none') # 设置坐标轴背景为透明
73 |
74 | ## 绘制参考线
75 | plt.plot(x1, 1 - x1, color='k', # 绘制参考线y=1-x
76 | linestyle='--') # 设置参考线为虚线
77 |
78 | ## 绘制单位圆
79 | plt.contour(xx1, xx2, zz, levels=[1], # 绘制模长为1的等高线,即单位圆
80 | colors='0.5', linestyles=['--']) # 设置颜色为黑色,线型为虚线
81 |
82 | ## 遍历时间步并绘制状态向量
83 | for i in np.arange(0, num_steps + 1): # 遍历每个时间步
84 | draw_vector(pi / np.linalg.norm(pi), colors[i], ax) # 绘制归一化状态向量
85 | draw_vector(pi, colors[i], ax) # 绘制原始状态向量
86 | pi = T @ pi # 更新状态向量,使用转移矩阵进行计算
87 |
88 | ## 设置图形样式
89 | ax.tick_params(left=False, bottom=False) # 隐藏坐标轴刻度线
90 | ax.set_xlim(-1.1, 1.1) # 设置x轴范围
91 | ax.set_ylim(-1.1, 1.1) # 设置y轴范围
92 | ax.axvline(x=0, color='0.5') # 绘制y轴
93 | ax.axhline(y=0, color='0.5') # 绘制x轴
94 | ax.spines['top'].set_visible(False) # 隐藏上边框
95 | ax.spines['right'].set_visible(False) # 隐藏右边框
96 | ax.spines['bottom'].set_visible(False) # 隐藏下边框
97 | ax.spines['left'].set_visible(False) # 隐藏左边框
98 | ax.grid(color=[0.8, 0.8, 0.8]) # 设置网格颜色
99 | plt.xticks(np.linspace(-1, 1, 21)) # 设置x轴刻度
100 | plt.yticks(np.linspace(-1, 1, 21)) # 设置y轴刻度
101 |
102 | ## 显示图形
103 | st.pyplot(fig=fig) # 使用Streamlit显示图形
104 |
--------------------------------------------------------------------------------
/Book3_Ch25_鸡兔同笼3__数学要素__从加减乘除到机器学习.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/Book3_Ch25_鸡兔同笼3__数学要素__从加减乘除到机器学习.pdf
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 《统计至简》五折入口:
2 | https://zhuanlan.zhihu.com/p/634253719
3 |
4 | 《数学要素》五折入口:
5 | https://zhuanlan.zhihu.com/p/620243026
6 |
7 | 《矩阵力量》五折入口:
8 | https://zhuanlan.zhihu.com/p/634253719
9 |
10 | 看个人情况,开源资源,永久有效哈。
11 |
12 | 纠错多的同学会得到赠书,以示感谢。
13 |
--------------------------------------------------------------------------------
/鸢尾花书_整体布局.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Visualize-ML/Book3_Elements-of-Mathematics/d1d0db94152b96c9029f605a4170cd148fe65b16/鸢尾花书_整体布局.pdf
--------------------------------------------------------------------------------