Ran Wei/数学系列
English
计算机科学与人工智能的数学基础 — Ran Wei

数学语言、数与函数

把公式读作计算过程的精确描述。学习确定定义域、复合函数、展开求和,并在翻译为 Python 之前检验数学主张。

6 小时4 个时段3 个实验12 道练习与 2 道拓展10 道自测题

完成后你能够

  • 区分定义、假设与待检验的主张。
  • 准确理解数系、区间与下标记法。
  • 明确函数的定义域、陪域与像,并计算复合函数。
  • 展开有限求和与乘积,包括空范围和嵌套情形。
  • 把数学约定翻译成代码,并用反例否定错误恒等式。

开始之前

需要学校阶段的算术与简单代数。如果分数、符号、方程或对数不熟悉,请先学可选代数复习。实验前阅读 Python 入门;不需要第三方包。

目录

学习计划

6 小时

时间包含练习,是估计值;可按需要拆分时段。可选拓展练习额外需要 25 分钟。进度保存在当前浏览器,中英文版本共享。

1

公式是一份小型规格说明

设想一个应用为搜索结果中的前四项计算分数。一位开发者从零计数,另一位从一开始;一位返回总和,另一位返回平均值。两种实现都能运行,也都产生数字,却回答了不同的问题。判断谁正确之前,我们需要精确说明预期计算的含义。

数学记法帮助我们做这件事:明确涉及的对象、允许的输入,以及输入与结果之间的关系。只有读懂这些承诺,公式才真正有用。仅仅认识符号并不够:求和范围一变,含义就变;函数的定义域一变,函数本身也可能改变。

贯穿本模块的任务很小:给定非负整数 nn,求前 nn 个正奇数的和。n=4n=4 时,各项为 1,3,5,71,3,5,7,结果为 1616;n=0n=0 时,没有任何项,结果为 00。我们将写出公式,把下标翻译为 Python,并区分几次成功运行与针对全部有效输入的主张。

阅读每个表达式时,始终问:这是什么对象?允许哪些值?结果必须表示什么? 今后阅读损失函数、概率模型、矩阵变换或算法成本时,同样的问题仍然适用。本模块建立数学语言;后续模块再发展证明和专门的数学工具。

实验前阅读 Python 入门。如果学校代数知识不够稳固,先做 入门诊断,并使用 可选复习。这些资源用于发现需要练习的内容,不是限制学习的门槛。

2

数学对象与数系

数学对象是能够描述并推理的事物,例如数、有序数对、集合、函数或数列。哪些运算有意义,取决于对象的种类。两个实数可以相加,但图书目录与温度是不同种类的对象。程序语言提供表示方式,数学描述则赋予表示以含义。

定义规定一个术语的含义。本系列规定自然数包含零:N={0,1,2,…}\mathbb{N}=\{0,1,2,\ldots\}。其他书籍可能用该符号表示 {1,2,…}\{1,2,\ldots\}。没有一项约定在所有文本中强制适用;应先声明再使用。特别要求正整数时,我们写 N>0\mathbb{N}_{>0}。零是否允许,关系到空输入、初始计数器和无效数量的处理。

假设说明推理或计算适用的环境。“令 n∈Nn\in\mathbb{N}”允许零而排除 2.52.5。主张是需要检验的陈述,例如“前 nn 个奇数之和等于 n2n^2”。它涉及每个允许的 nn;给出求和定义并不自动证明这个主张。定理是从明确假设和认可规则出发,已经用证明建立的主张。模块 04 将系统介绍证明方法。

常见数系构成层次关系。整数 Z\mathbb{Z} 包含负的整值数;有理数 Q\mathbb{Q} 包含 p/qp/q,其中 p,qp,q 为整数且 q≠0q\ne0;实数 R\mathbb{R} 还包括 2\sqrt{2} 等无理数。小数只是书写方式:0.5=1/20.5=1/2 是有理数,而 2\sqrt{2} 的无限小数展开不终止也不循环。

数系 例子 常见用途
N\mathbb{N} 0,1,40,1,4 计数与非负下标
Z\mathbb{Z} −3,0,7-3,0,7 有符号差值与整数位置
Q\mathbb{Q} 1/3,−7/2,0.1251/3,-7/2,0.125 精确比值与比例
R\mathbb{R} 2,π,1/3\sqrt{2},\pi,1/3 测量与连续模型
C\mathbb{C} 2+3i2+3\mathrm{i} 后续旋转与谱方法的拓展

属于与包含使用不同符号。3∈N3\in\mathbb{N} 表示一个对象属于一个集合;N⊆Z\mathbb{N}\subseteq\mathbb{Z} 表示前一个集合的每个元素也属于后一个集合。为了声明定义域,我们先使用这部分集合语言;模块 03 再深入学习集合运算。

数系的包含关系N 包含于 Z,Z 包含于 Q,Q 包含于 R。框的大小不表示元素数量。实数 R:例如 √2、π有理数 Q:例如 1/3、−7/2整数 Z:例如 −3、−1自然数 N:0、1、2、…本系列包含零
图 1.1

自然数、整数、有理数与实数相互嵌套。标签举出各层新增的例子;框表示包含关系,不表示各集合中数的数量。

例题详解
区分数值与表示方式

−6/3=−2-6/3=-2 是整数、有理数与实数,但按本系列约定不是自然数。00 属于上述四个数系。有限小数 1.4141.414 等于有理数 707/500707/500;它是 2\sqrt{2} 的近似值,不是该数的另一种精确写法。

记录数量必须是自然数。测得的电压可以建模为实数,但计算机保存的是有限近似。选择实数模型不意味着每个实数都有精确机器表示。

复数写作 a+bia+b\mathrm{i},其中 a,b∈Ra,b\in\mathbb{R} 且 i2=−1\mathrm{i}^2=-1。这里只作预览,不是实验的先修条件。实数对应 b=0b=0 的特殊情况。谱方法和傅里叶方法会用到复数;当前计算使用实数与整数下标。

公式出现字母时,要说明其角色,不要仅凭字母外形猜测。变量可以在允许值中变化;参数在某次分析中保持固定;常量在当前环境中取指定值。这些角色取决于上下文。在 fa(x)=ax+1f_a(x)=ax+1 中,可以把 aa 视为参数、xx 视为输入;以后从数据拟合 aa 时,它又成为变化的量。

检验理解

记录数量保存为数值 4.0 时,数学上的数量是否因此不再是整数?4.5 能作为记录数量吗?

查看答案

4.0=44.0=4 在数学上仍是整数,但 Python 的浮点数与整数是不同软件表示。约定可以明确要求整数表示。4.54.5 不是整数,不能作为该计数任务的有效数量。应区分数学定义域与软件类型政策。

3

符号 相等 区间与下标

== 表示两个表达式指向同一个值,具有对称性:若 a=ba=b,则 b=ab=a。它不表示“继续下一步”或“保存新值”。≠\ne 表示不相等;<< 与 ≤\le 比较有序实数。x≤3x\le3 包含边界 33,x<3x<3 排除它。0≤x<10\le x<1 是两个条件同时成立。

数学方程 x=x+1x=x+1 没有实数解,因为两边减去 xx 会得到 0=10=1。Python 的 x = x + 1 则先用旧值计算右侧,再把结果赋给左侧名称;相等比较使用 ==。数学文本也可能用 x:=3x:=3 或“定义 xx 为 3”,把定义与待求解方程分开。这些写法表示不同操作。

运算优先级也影响含义。通常 −32=−(32)=−9-3^2=-(3^2)=-9,因为先乘方再处理外面的负号;(−3)2=9(-3)^2=9 则把负号纳入底数。分数线将分子和分母各自分组;代码 1/(x-2) 保留了这种结构,而 1/x-2 是另一表达式。翻译公式时,即使默认优先级正确,也可以加括号帮助读者理解。

区间规定一段实数范围。方括号包含端点,圆括号排除端点:[0,1][0,1] 包含两端,(0,1)(0,1) 排除两端,[0,1)[0,1) 只包含左端。无穷不是能被包含的实数端点,因此正实数范围写为 (0,∞)(0,\infty)。区间 [0,4][0,4] 不同于五元素集合 {0,1,2,3,4}\{0,1,2,3,4\}:区间还包含 1/21/2 与 2\sqrt{2}。

绝对值表示到零的距离:x≥0x\ge0 时 ∣x∣=x|x|=x,x<0x<0 时 ∣x∣=−x|x|=-x。它总是非负,因此 ∣−3∣=3|-3|=3。∣x∣<2|x|<2 表示距离零小于二,等价于 −2<x<2-2<x<2。以后近似误差和容差也会用到这种距离记法。

例题详解
翻译边界条件

分数满足 0≤s<10\le s<1 时被接受。代码对应 0 <= s < 1。00 与 0.50.5 满足条件;11 与 −0.1-0.1 不满足。把 < 1 改成 <= 1 会改变边界处的约定,即使典型数据中从未出现这个边界值。

下标标记分量或项。数列 a0,a1,a2a_0,a_1,a_2 中,a2a_2 是标记为二的项,不是 a⋅2a\cdot2,也不是 a2a^2。上标经常表示乘方,但含义仍取决于声明:以后可能用 x(t)x^{(t)} 表示第几次迭代。括号与解释帮助区分这两种含义。

奇数任务使用 ai=2i+1a_i=2i+1,整数下标为 i=0,1,…,n−1i=0,1,\ldots,n-1。当 n=4n=4 时,下标为 0,1,2,30,1,2,3,对应项为 1,3,5,71,3,5,7。最后下标是三,但项数是四。若从 i=1i=1 开始却不改变公式,就会从 33 开始,描述另一数列。

∑i=03(2i+1)\sum_{i=0}^{3}(2i+1) 表示依次代入允许的整数下标,再相加。展开为 (2⋅0+1)+(2⋅1+1)+(2⋅2+1)+(2⋅3+1)=16(2\cdot0+1)+(2\cdot1+1)+(2\cdot2+1)+(2\cdot3+1)=16。大写希腊字母 sigma 是聚合指令。第 5 节会深入讨论作用范围与嵌套形式;这些知识已经足够跟踪实验 1。

注意

数学求和上下界都包含在范围内;Python 的 range(start, stop) 不包含 stop。零到三使用 range(4),一到四使用 range(1,5)。官方 Python range 教程 解释该约定。

还要区分精确相等与近似。2≈1.414\sqrt{2}\approx1.414 承认二者存在差异。显示三位小数不能证明底层数值相等。实验中的整数求和使用精确整数运算;浮点计算需要明确容差。模块 29 将解释更复杂情形下如何选择数值比较方式。

检验理解

把 i=1,2,…,4i=1,2,\ldots,4 翻译成 Python range。解释 a2a_2 与 a2a^2、(0,1](0,1] 与 {0,1}\{0,1\} 的区别。

查看答案

使用 range(1,5)。前者标记项或分量,后者将数值平方。区间包含所有大于零且不超过一的实数,包括 1/21/2 而排除零;有限集合则恰好包含零与一。

4

函数 定义域与复合

函数为其定义域中的每个输入指定唯一输出。f:D→Cf:D\to C 给出定义域 DD 与陪域 CC。所有输出必须属于 CC,但不要求 CC 的每个元素都被产生。实际达到的输出集合叫像:f(D)={f(x):x∈D}f(D)=\{f(x):x\in D\}。这一区分关系到反函数是否存在,以及一个候选输出是否可能出现。

公式只是描述函数的一种方法,并不是完整规格。同一表达式配上不同定义域,可以描述不同函数。f(x)=x2f(x)=x^2 在全部实数上定义时,像为 [0,∞)[0,\infty);定义域为 {0,1,2}\{0,1,2\} 时,像为 {0,1,4}\{0,1,4\}。两者都能选择 R\mathbb{R} 为陪域,但陪域中的未达到值不是函数输出。

定义域 陪域与像0 映射到 1,1 映射到 3,2 映射到 5;陪域还有未使用的 9。定义域 D陪域 C0113259像 = {1, 3, 5};9 未被达到
图 1.2

f(x)=2x+1f(x)=2x+1 在定义域 {0,1,2}\{0,1,2\} 上产生 {1,3,5}\{1,3,5\}。声明的陪域还包含未达到的 99。每个输入恰有一条输出箭头;陪域有未使用值是允许的。

定义域限制可能来自表达式,也可能来自问题。实数表达式 r(x)=1/(x−2)r(x)=1/(x-2) 不允许 x=2x=2,因为除零未定义;实数平方根要求被开方数非负。计数函数可以排除负输入,即使其代数表达式能机械代入负值。先说明问题本身的限制,再讨论表达式是否能计算。

函数也可以分段定义:

h(x)={2x+1,x<0,x2,x≥0.h(x)=\begin{cases}2x+1,&x<0,\\x^2,&x\ge0.\end{cases}

条件选择规则,并且必须为定义域中每个输入提供唯一结果。这里每个实数恰好属于一个分支,边界 x=0x=0 也被覆盖。若分支重叠且给出不一致输出,就不是有效函数;若漏掉一部分输入,就没有覆盖声称的定义域。

例题详解
在边界处计算分段函数

第一分支给出 h(−2)=2(−2)+1=−3h(-2)=2(-2)+1=-3;第二分支给出 h(3)=9h(3)=9 与 h(0)=0h(0)=0。零不使用第一分支,因为其条件是严格小于。Python 可先写 if x < 0: return 2*x + 1,再写 return x*x。边界测试属于检查数学规格的一部分。

复合是把一个函数的输出交给另一个函数。(f∘g)(x)=f(g(x))(f\circ g)(x)=f(g(x)) 中外层函数写在左边,但先执行 gg。有效输入必须属于 gg 的定义域,且中间结果必须属于 ff 的定义域。若 gg 的所有输出都满足外层要求,复合在 gg 的全部定义域上成立;否则必须进一步限制允许输入。

例题详解
复合顺序改变结果

令 f(t)=2t+1f(t)=2t+1,g(t)=t2g(t)=t^2,定义域均为实数。于是

f(g(x))=2x2+1,g(f(x))=(2x+1)2.f(g(x))=2x^2+1,\qquad g(f(x))=(2x+1)^2.

x=3x=3 时,第一种先得到 g(3)=9g(3)=9,再得到 f(9)=19f(9)=19;第二种先得到 f(3)=7f(3)=7,再得到 g(7)=49g(7)=49。两者是不同函数。不能仅因输入类型相同,就随意交换复合次序。

两种复合顺序相同输入 3:先平方再乘二加一得到 19;先乘二加一再平方得到 49。先 g,再 f:f(g(3))先 f,再 g:g(f(3))3g(t) = t²9f(t) = 2t+1193f(t) = 2t+17g(t) = t²49
图 1.3

两条路径从相同输入出发,使用相同规则,却产生不同输出。沿实际计算顺序阅读箭头,而不是把书写的复合从左往右执行。

若改成 f(t)=ln⁡(t−1)f(t)=\ln(t-1)、g(x)=x2g(x)=x^2,外层要求 t>1t>1,因此复合要求 x2>1x^2>1,即 x<−1x<-1 或 x>1x>1。内层平方允许零,但整个复合不允许。只检查原输入是否满足内层条件,会漏掉中间值的定义域错误。

交互演示

选择两个规则、改变顺序,并输入 −4-4 至 44 的值。先在 x=3x=3 重现 1919 与 4949;再选择 f(t)=ln⁡(t−1)f(t)=\ln(t-1)、g(t)=t2g(t)=t^2,比较 x=0x=0、x=1x=1、x=2x=2。图只显示垂直范围内的值。看不到点可能意味着定义域无效,也可能意味着数值超出显示范围;请查看计算信息。

没有 JavaScript 时,使用上面的手工计算:对数例子中 f(g(0))f(g(0)) 与 f(g(1))f(g(1)) 均未定义,而 f(g(2))=ln⁡3f(g(2))=\ln3。

反函数唯一地逆转映射。实数函数 f(x)=2x+1f(x)=2x+1 的反函数为 f−1(y)=(y−1)/2f^{-1}(y)=(y-1)/2;两个方向的复合都会恢复原值。f−1f^{-1} 表示反映射,不是倒数 1/f1/f。全部实数上的平方不能唯一恢复输入,因为 22 与 −2-2 都产生 44。将平方的定义域和陪域都限制为 [0,∞)[0,\infty),才得到反函数 y\sqrt{y}。

程序实现也不一定是仅关于其显式参数的数学函数。读取时钟、可变全局变量或随机生成器的过程,可能对相同显式输入返回不同结果。需要确定性映射时,应把额外状态纳入模型。后续概率模块会直接建模随机输出。

检验理解

对于 f(t)=1/(t−2)f(t)=1/(t-2)、g(x)=x+1g(x)=x+1,给出 f(g(x))f(g(x)) 的公式与定义域。只检查 gg 接受输入是否足够?

查看答案

复合为 1/(x−1)1/(x-1),定义域是实数 x≠1x\ne1。x=1x=1 对内层有效,却产生外层拒绝的 22。原输入与中间输出都要检查定义域。

5

乘方 对数与增长

正整数指数表示重复相乘,因此 a3=aaaa^3=aaa。非零底数的零次方是 a0=1a^0=1,负整数次方是 a−k=1/aka^{-k}=1/a^k。底数限制不可省略:零的负次方会要求除零。000^0 在不同环境中有不同约定;本模块不为它规定普遍的实数解释。

在有效定义域内,乘方满足 aras=ar+sa^r a^s=a^{r+s} 与 (ar)s=ars(a^r)^s=a^{rs}。正实数底数允许将这些关系自然推广到实数指数。负底数和非整数指数的实数定义域则更复杂,例如 (−1)1/2(-1)^{1/2} 不是实数。不能仅凭符号相似,就把正底数规则套到所有表达式。

指数函数固定底数、改变指数:2x2^x 的输入是 xx。幂函数 x2x^2 则改变底数、固定指数。x=2x=2 时二者都给出 44;x=3x=3 时分别为 88 与 99;x=4x=4 时又都为 1616。若干重合值并不说明函数相同。实验 2 在明确范围内比较它们;模块 06 再研究更长远的增长。

对数询问什么指数会产生某个正值。实数底数 a>0a>0、a≠1a\ne1 时,log⁡ax=y\log_a x=y 表示 ay=xa^y=x,要求 x>0x>0。它是指数映射的反函数。自然对数 ln⁡x\ln x 使用底数 ee,约为 2.718282.71828 的正无理数。本系列未注明底数的数学 log⁡\log 默认表示自然对数。

定义域也是恒等式的一部分。对任意实数 yy,ln⁡(ey)=y\ln(e^y)=y;对正数 xx,eln⁡x=xe^{\ln x}=x。后一表达式在零或负实数上未定义。这种计算器报错反映所规定实函数的定义域,并不是偶然的软件不便。

例题详解
平移后的对数需要平移后的定义域

令 q(x)=ln⁡(x−1)q(x)=\ln(x-1)。对数参数必须为正,因此 x−1>0x-1>0,即 x>1x>1。定义域是 (1,∞)(1,\infty),不是 (0,∞)(0,\infty)。q(2)=ln⁡1=0q(2)=\ln1=0,q(1+e)=1q(1+e)=1;x=1x=1 时参数为零,实数表达式未定义。

对正实数 u,vu,v,对数将乘法转成加法:

ln⁡(uv)=ln⁡u+ln⁡v,ln⁡(u/v)=ln⁡u−ln⁡v.\ln(uv)=\ln u+\ln v,\qquad \ln(u/v)=\ln u-\ln v.

乘积恒等式来自指数规则:写成 u=eru=e^r、v=esv=e^s,则 uv=er+suv=e^{r+s},取自然对数得到 r+sr+s。参数与商必须仍然满足定义域要求。对 u>0u>0,还成立 ln⁡(ur)=rln⁡u\ln(u^r)=r\ln u。以后,这些关系会把独立概率的乘积转成对数似然之和。

加法没有对应的一般恒等式。取 u=v=1u=v=1,ln⁡(u+v)=ln⁡2\ln(u+v)=\ln2 为正,但 ln⁡u+ln⁡v=0\ln u+\ln v=0。一个有效反例足以否定声称对全部正输入成立的恒等式,却不能自动建立另一条公式;乘积规则需要自己的解释。

例题详解
换底并保留原有关系

当 a>0a>0、a≠1a\ne1、x>0x>0 时,

log⁡ax=ln⁡xln⁡a.\log_a x=\frac{\ln x}{\ln a}.

令 y=log⁡axy=\log_a x,于是 ay=xa^y=x。取自然对数得到 yln⁡a=ln⁡xy\ln a=\ln x。由于 a≠1a\ne1,分母不为零,可以相除。因此 log⁡28=ln⁡8/ln⁡2=3\log_2 8=\ln8/\ln2=3。精确关系由比值表达,而不是任意一个经过舍入的小数表达。

比较增长必须说明输入范围和目的。把 ln⁡n\ln n 乘以正的常数 1/ln⁡21/\ln2 会改变数值,却不改变随 nn 增长的总体形态。在编码和信息计算中,底数仍重要,因为单位会改变:二进制对数对应比特,自然对数对应纳特。信息论模块会再次讨论这些单位。

图像只能提供显示窗口内的证据,不能证明全部正输入上的性质。指数函数可能在某段范围内小于多项式,却在更后面增长更快。坐标轴也必须检查:对数坐标会改变数值间的显示间距。实验 2 使用相同的普通坐标轴;曲线离开可见矩形,不意味着函数不再存在。

检验理解

ln⁡(3−x)\ln(3-x) 允许哪些输入?ln⁡(a+b)=ln⁡a+ln⁡b\ln(a+b)=\ln a+\ln b 是否对全部正数 a,ba,b 成立?用计算解释。

查看答案

要求 3−x>03-x>0,因此 x<3x<3。取 a=b=1a=b=1,左侧 ln⁡2>0\ln2>0,右侧为 00。两侧都在定义域内,这是有效反例。

6

有限求和 乘积与作用范围

有限求和在声明的下标范围内聚合各项。求和符号绑定其中的下标:∑i=1nai\sum_{i=1}^n a_i 中,ii 逐一取一到 nn 的整数值,而 nn 仍是控制范围的参数。绑定范围之外的字母可能有另一含义。这与程序循环变量的作用范围相似。

可靠地阅读求和,需要确定四部分:下标名称、起点、终点和被计算的项。先展开小例子,再尝试化简:

∑i=14(i+2)=(1+2)+(2+2)+(3+2)+(4+2)=18.\sum_{i=1}^{4}(i+2)=(1+2)+(2+2)+(3+2)+(4+2)=18.

共有四项。不能把下标或最后一项简单乘以上界作为捷径。改成 4(4+2)=244(4+2)=24,等于把末项错误地使用四次。

下标是绑定变量,也称哑变量。完整改名不改变总和:∑i=14i2=∑j=14j2\sum_{i=1}^4 i^2=\sum_{j=1}^4 j^2。但改名不能捕获原有变量。在 ∑i=1n(x+i)\sum_{i=1}^n(x+i) 中,xx 是自由变量,ii 被绑定。若把绑定下标改成 xx,却不保留原来的自由输入,就悄悄改变了表达式。应选择不同名称,类似避免覆盖函数参数。

有限求和可以使用普通加法规则重新排列和分配。常数 cc 满足

∑i=1n(cai+bi)=c∑i=1nai+∑i=1nbi.\sum_{i=1}^n(ca_i+b_i)=c\sum_{i=1}^n a_i+\sum_{i=1}^n b_i.

展开两侧,就能看到每项恰好出现一次。这是当前加法与乘法的性质,并不证明所有函数满足 f(a+b)=f(a)+f(b)f(a+b)=f(a)+f(b)。无限求和重新排列时还需要收敛条件;这里只讨论有限情形。

空和为零:没有贡献时,已有累计值不变。奇数任务中,n=0n=0 使零到 n−1n-1 的范围为空,不是需要计算一个负下标末项。结果来自聚合约定,不是把不存在的项假装为零。

有限乘积使用 ∏\prod,例如 ∏i=14i=1⋅2⋅3⋅4=24\prod_{i=1}^4 i=1\cdot2\cdot3\cdot4=24。空积为一,因为没有因子时,已有乘积不变。若空积为零,任何普通乘积拆成非空部分与空部分后都会消失。这些单位元解释了 sum([]) 与 math.prod([])。

例题详解
用两种下标约定表示同样四个奇数

从零开始:∑i=03(2i+1)=16\sum_{i=0}^{3}(2i+1)=16;从一开始必须改项公式:∑j=14(2j−1)=16\sum_{j=1}^{4}(2j-1)=16。转换关系是 j=i+1j=i+1。若只改起点、不改原项,得到 3+5+7+9=243+5+7+9=24,对应另一任务。

双重求和包含两个聚合指令:

∑i=12∑j=13(10i+j).\sum_{i=1}^{2}\sum_{j=1}^{3}(10i+j).

先固定外层 ii,完成内层 jj 的求和,再把内层结果相加。i=1i=1 时,各项 11,12,1311,12,13 合计 3636;i=2i=2 时,各项 21,22,2321,22,23 合计 6666;整体为 102102。两个外层值各对应三个内层值,因此共有六项。

矩形双重求和第一行为 11、12、13,总和 36;第二行为 21、22、23,总和 66;合计 102。项 = 10i + jj = 1j = 2j = 3i = 1111213= 36i = 2212223= 66总和:36 + 66 = 102
图 1.4

矩形下标网格显示全部六项。每行对应一个外层下标;相加各行总和就是外层求和。这是下标示意图,不要求先学矩阵代数。

因为是有限矩形,先加列也相同:(11+21)+(12+22)+(13+23)=32+34+36=102(11+21)+(12+22)+(13+23)=32+34+36=102。非矩形范围需要更谨慎。在 ∑i=13∑j=1ij\sum_{i=1}^3\sum_{j=1}^i j 中,内层上界依赖 ii。各行分别为 11、1,21,2、1,2,31,2,3,总和 1010。不转换有效下标对而直接交换两个求和符号,会改变范围。

求和后仍保留的变量决定输出含义。s(x)=∑i=13(x+i)s(x)=\sum_{i=1}^3(x+i) 中绑定下标消失,但输入 xx 保留;展开得到 s(x)=3x+6s(x)=3x+6。tj=∑i=12aijt_j=\sum_{i=1}^2 a_{ij} 中,jj 仍是自由下标,用来标记哪一列的总和。模块 09 使用数组时,这一区分能避免形状与轴的错误。

矩形双重求和使用外层 range(1,3) 与内层 range(1,4)。三角形例子使用外层 range(1,4) 和内层 range(1,i+1)。扩大输入之前,检查极小例子与空范围。一个很大的、看起来合理的结果,不能显示究竟遗漏了哪些下标。

检验理解

展开 ∑i=02∑j=12(i+j)\sum_{i=0}^{2}\sum_{j=1}^{2}(i+j)。哪些符号被绑定?∑i=02(x+i)\sum_{i=0}^{2}(x+i) 中哪个变量仍然自由?

查看答案

各行是 1+21+2、2+32+3、3+43+4,总和 1515。双重求和绑定 ii 与 jj。第二个表达式只绑定 ii,xx 自由;展开为 3x+33x+3。

7

约定 主张与代码翻译

数学约定说明允许的输入与结果必须满足的关系。奇数任务输入为非负整数 nn,输出为整数总和

S(n)=∑i=0n−1(2i+1),S(n)=\sum_{i=0}^{n-1}(2i+1),

其中空和为零,输入不被修改。负数量、非整数量,以及要求平均值而非总和,都不属于该规格。软件政策另行说明无效输入如何处理;实验抛出清晰的 ValueError。

逐项翻译:数学数量成为 Python 整数;包含 n−1n-1 的范围成为 range(n);项写为 2 * i + 1,代码需要乘法运算符;累计值从零开始,每次加入一项。这比把符号机械复制到解释方式不同的语言更可靠。

例题详解
运行之前先跟踪约定

n=4n=4 时,下标依次为 0,1,2,30,1,2,3,项为 1,3,5,71,3,5,7,累计值为 1,4,9,161,4,9,16。n=0n=0 时没有迭代,初始值 00 已是正确输出;n=1n=1 时,只加入零下标的项,得到 11。

这种跟踪检查经常暴露起止位置错误的边界情形,却不是对全部非负数量的正确性证明。以后将用不变式完成一般论证。

SS 的定义与 S(n)=n2S(n)=n^2 的主张角色不同。定义说明计算内容,恒等式声称另一个表达式对全部有效 nn 给出相同值。n=4n=4 的检查只确认一个案例。一般恒等式可用模块 04 的归纳法,或本模块可选练习中的有限求和代数论证建立。

否定全称主张常常比证明更容易。否定“每个实函数都有加性”,可取 f(x)=x2f(x)=x^2、a=2a=2、b=3b=3:f(a+b)=25f(a+b)=25,而 f(a)+f(b)=13f(a)+f(b)=13。所有输入和中间值都有效,因此反例成立。若把未定义的对数作为“反例”,就不能检验只对正参数声称的恒等式。

区分三种故障。规格故障是公式描述了错误任务,如要求总和却写成平均值。翻译故障是代码实现了错误表达式,如该用 range(n) 却写 range(1,n)。数值故障是机器算术没有足够好地近似预期计算,如指数溢出或相等检查不合适。不同故障需要不同修复。

AI 论文写 L(θ)=1n∑i=1nℓi(θ)L(\theta)=\frac1n\sum_{i=1}^n\ell_i(\theta) 时,同样的基本技能仍适用:θ\theta 自由、ii 绑定;nn 必须为正,因为平均值不能除以零;求和改成平均会改变尺度。你暂时不需要会最小化它,也能读懂所声明的关系;后续微分与优化再提供进一步工具。

不要默默给公式增加情况。若将来要求 n=0n=0 返回“无分数”而非零,应修改约定与检查;若函数输入从标量改成数组,应声明新的输入输出形状。数学精确性让这些选择清晰可见,便于讨论与验证。

检验理解

sum(2*i+1 for i in range(1,n)) 为什么不符合约定?给出揭示错误的最小正输入。

查看答案

它遗漏下标零,其项为 11。n=1n=1 时,错误范围为空,返回 00,约定却要求 11。n=0n=0 时两种代码碰巧都返回零,所以只检查空情况会漏掉故障。

8

常见误解

现象 原因 修复
“数量为 4,所以零起始末下标为 4” 混淆数量与标签 写出下标 0,1,2,3
内层有效,外层却失败 只检查原输入 检查中间值是否属于外层定义域
假定每个陪域值都能达到 混淆陪域与像 求出实际达到值或描述像
几个例子正确便接受主张 混淆证据与证明 明确量词,寻找论证或有效反例
对数被分配到加法上 把乘积规则用于另一运算 使用 1,1 等正输入比较两式
“曲线在这里结束” 混淆显示范围与定义域 说明定义域,检查是否离开坐标范围
把浮点结果当成精确值 忽略表示与舍入 标注近似,使用有理由的容差
9

准备实验

若脚本中有不熟悉的语法,先读 Python 入门。把各脚本下载到能找到的文件夹,在该文件夹打开终端,运行 python lab1_sums.py、python lab2_functions.py 或 python lab3_diagnose.py。Windows 可能需要 py,macOS/Linux 常用 python3;检查所选解释器为 Python 3.11 或更新版本。脚本只使用标准库。

下面提供完整脚本与网页构建器实际捕获的输出。执行之前先阅读问题,预测主要数值。本地改变脚本会改变输出;发布的输出对应未修改版本。实验 2 生成的图像可以直接用浏览器打开。

10

实验 1 展开并跟踪有限求和

目标: 将整数范围与项及其总和联系起来。先预测 n=0,1,4,6n=0,1,4,6 的项和总和,再运行代码。

下载 lab1_sums.py

"""Read finite sums and products. Run with Python 3.11+; no packages needed."""
from math import prod


def odd_sum(n):
    """Sum the first n positive odd integers; n must be a nonnegative int."""
    if isinstance(n, bool) or not isinstance(n, int) or n < 0:
        raise ValueError("n must be a nonnegative integer")
    terms = [2 * i + 1 for i in range(n)]
    return terms, sum(terms)


def rectangular_sum(rows, columns):
    """Sum 10*i+j for mathematical indices 1..rows and 1..columns."""
    return [[10 * i + j for j in range(1, columns + 1)]
            for i in range(1, rows + 1)]


if __name__ == "__main__":
    for n in (0, 1, 4, 6):
        terms, total = odd_sum(n)
        assert total == n * n
        print(f"n={n}: terms={terms}, sum={total}, n*n={n*n}")
    grid = rectangular_sum(2, 3)
    total = sum(sum(row) for row in grid)
    assert total == 102
    print(f"grid={grid}, double_sum={total}")
    assert sum([]) == 0 and prod([]) == 1
    print(f"empty_sum={sum([])}, empty_product={prod([])}")
    print("Checks passed on these inputs; examples alone are not a general proof.")
输出
n=0: terms=[], sum=0, n*n=0
n=1: terms=[1], sum=1, n*n=1
n=4: terms=[1, 3, 5, 7], sum=16, n*n=16
n=6: terms=[1, 3, 5, 7, 9, 11], sum=36, n*n=36
grid=[[11, 12, 13], [21, 22, 23]], double_sum=102
empty_sum=0, empty_product=1
Checks passed on these inputs; examples alone are not a general proof.

探索: 改为 n=2,3,8n=2,3,8,预测结果。解释二维表为何有六项且总和为 102102。检查空积,并解释为什么一是相应单位元。

书面结果: 展示一次完整展开与跟踪,明确断言检查了哪些输入,解释为何这些检查没有证明所有 nn 上的恒等式。

11

实验 2 比较函数与定义域

目标: 联系数值、公式与图像。先预测 x=0x=0 的一行,以及 x=3x=3 时两种复合。对数使用实数定义域 x>0x>0。

下载 lab2_functions.py

"""Compare four functions and write an SVG plot using only the standard library.

Run: python lab2_functions.py
Optional: python lab2_functions.py --output functions.svg
"""
import argparse
from html import escape
import math
from pathlib import Path


def logarithm(x):
    if x <= 0:
        raise ValueError("ln(x) requires x > 0")
    return math.log(x)


FUNCTIONS = [("2*x+1", lambda x: 2 * x + 1, "#2563eb"),
             ("x*x", lambda x: x * x, "#7e22ce"),
             ("2**x", lambda x: 2 ** x, "#15803d"),
             ("ln(x)", logarithm, "#c2410c")]


def make_plot(destination):
    width, height = 760, 420
    left, right, top, bottom = 60, 720, 45, 335
    x_min, x_max, y_min, y_max = -2, 4, -4, 18
    def px(x):
        return left + (x - x_min) / (x_max - x_min) * (right - left)
    def py(y):
        return bottom - (y - y_min) / (y_max - y_min) * (bottom - top)
    parts = [f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {width} {height}" role="img" aria-labelledby="title desc">',
             '<title id="title">Four functions over stated domains</title>',
             '<desc id="desc">Linear, square, exponential and natural logarithm. The logarithm has no curve at nonpositive inputs. All curves share the same axes.</desc>',
             '<rect width="760" height="420" fill="white"/>',
             '<g font-family="sans-serif" font-size="13" fill="#475569">']
    for x in range(-2, 5):
        parts.append(f'<path d="M{px(x):.2f},{top} V{bottom}" stroke="#e2e8f0"/>')
        parts.append(f'<text x="{px(x):.2f}" y="355" text-anchor="middle">{x}</text>')
    for y in range(-4, 19, 2):
        parts.append(f'<path d="M{left},{py(y):.2f} H{right}" stroke="#e2e8f0"/>')
        parts.append(f'<text x="48" y="{py(y)+4:.2f}" text-anchor="end">{y}</text>')
    parts.extend([f'<path d="M{left},{py(0):.2f} H{right} M{px(0):.2f},{top} V{bottom}" stroke="#475569"/>',
                  '<text x="735" y="355">x</text><text x="35" y="30">y</text></g>'])
    for index, (label, function, colour) in enumerate(FUNCTIONS):
        commands = []
        connected = False
        for step in range(601):
            x = x_min + step * (x_max - x_min) / 600
            try:
                y = function(x)
            except ValueError:
                connected = False
                continue
            if not y_min <= y <= y_max:
                connected = False
                continue
            commands.append(f'{"L" if connected else "M"}{px(x):.2f},{py(y):.2f}')
            connected = True
        parts.append(f'<path d="{" ".join(commands)}" fill="none" stroke="{colour}" stroke-width="2.5"/>')
        legend_x = 70 + index * 170
        parts.append(f'<path d="M{legend_x},387 h20" stroke="{colour}" stroke-width="3"/>')
        parts.append(f'<text x="{legend_x+27}" y="391" font-family="monospace" font-size="14">{escape(label)}</text>')
    parts.append('</svg>')
    destination.parent.mkdir(parents=True, exist_ok=True)
    destination.write_text('\n'.join(parts), encoding='utf-8')


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--output', type=Path, default=Path('functions.svg'))
    args = parser.parse_args()
    print('x      2*x+1      x*x      2**x      ln(x)')
    for x in (-2, -1, 0, 1, 2, 4):
        values = []
        for _, function, _ in FUNCTIONS:
            try:
                values.append(f'{function(x):9.4f}')
            except ValueError:
                values.append('undefined')
        print(f'{x:2d} ' + ' '.join(values))
    f = lambda x: 2 * x + 1
    g = lambda x: x * x
    assert f(g(3)) == 19 and g(f(3)) == 49
    print(f'f(g(3))={f(g(3))}; g(f(3))={g(f(3))}')
    assert math.isclose(logarithm(4) / logarithm(2), 2.0)
    try:
        logarithm(0)
    except ValueError as error:
        print(f'domain check: {error}')
    else:
        raise AssertionError('zero must be rejected')
    make_plot(args.output)
    print(f'Plot written: {args.output.name}')
输出
x      2*x+1      x*x      2**x      ln(x)
-2   -3.0000    4.0000    0.2500 undefined
-1   -1.0000    1.0000    0.5000 undefined
 0    1.0000    0.0000    1.0000 undefined
 1    3.0000    1.0000    2.0000    0.0000
 2    5.0000    4.0000    4.0000    0.6931
 4    9.0000   16.0000   16.0000    1.3863
f(g(3))=19; g(f(3))=49
domain check: ln(x) requires x > 0
Plot written: functions.svg
同一坐标轴上的一次、平方、指数与对数曲线;对数仅在正输入上有定义。
可下载的 Python 脚本生成的图像。

探索: 打开 functions.svg,找到各条曲线并检查对数从哪里出现。把表格输入改成 0.5,1,3;这样修改时,应同时把整数输入标签改为浮点格式。解释 x≤0x\le0 时对数未定义,与有效曲线超出纵轴上限的区别。

书面结果: 写出得到 1919 与 4949 的中间值,描述四个函数的定义域,解释为何 [−2,4][-2,4] 上的图像不足以证明最终增长性质。

12

实验 3 诊断错误翻译与恒等式

目标: 在修复之前用有效反例定位错误。先预测少一项的总和,以及平方函数的反例。

下载 lab3_diagnose.py

"""Find counterexamples and repair a contract, an index range, and an identity."""
import math


def bad_odd_sum(n):
    return sum(2 * i + 1 for i in range(1, n))


def odd_sum(n):
    if isinstance(n, bool) or not isinstance(n, int) or n < 0:
        raise ValueError('n must be a nonnegative integer')
    return sum(2 * i + 1 for i in range(n))


def shifted_log(x):
    if x <= 1:
        raise ValueError('ln(x-1) requires x > 1')
    return math.log(x - 1)


if __name__ == '__main__':
    n = 4
    print(f'off-by-one: n={n}, faulty={bad_odd_sum(n)}, repaired={odd_sum(n)}, expected={n*n}')
    assert bad_odd_sum(n) != n * n and odd_sum(n) == n * n
    f = lambda x: x * x
    a, b = 2, 3
    print(f'non-additive square: f(a+b)={f(a+b)}, f(a)+f(b)={f(a)+f(b)}')
    assert f(a + b) != f(a) + f(b)
    lhs, rhs = math.log(a + b), math.log(a) + math.log(b)
    print(f'false log identity: ln(a+b)={lhs:.6f}, ln(a)+ln(b)={rhs:.6f}')
    assert not math.isclose(lhs, rhs)
    assert math.isclose(math.log(a * b), rhs)
    print(f'correct product identity: ln(a*b)={math.log(a*b):.6f}')
    for x in (1, 2):
        try:
            print(f'shifted_log({x})={shifted_log(x):.6f}')
        except ValueError as error:
            print(f'shifted_log({x}) rejected: {error}')
    for invalid in (-1, 2.5, True):
        try:
            odd_sum(invalid)
        except ValueError:
            print(f'odd_sum({invalid!r}) rejected')
        else:
            raise AssertionError('invalid input accepted')
    print('Repairs preserve the stated domains; counterexamples refute the false claims.')
输出
off-by-one: n=4, faulty=15, repaired=16, expected=16
non-additive square: f(a+b)=25, f(a)+f(b)=13
false log identity: ln(a+b)=1.609438, ln(a)+ln(b)=1.791759
correct product identity: ln(a*b)=1.791759
shifted_log(1) rejected: ln(x-1) requires x > 1
shifted_log(2)=0.000000
odd_sum(-1) rejected
odd_sum(2.5) rejected
odd_sum(True) rejected
Repairs preserve the stated domains; counterexamples refute the false claims.

探索: 用 n=1n=1 检查最小正边界;为对数比较选择其他正数 a,ba,b;用 shifted_log(0) 和 shifted_log(3) 检查定义域边界两侧。不要为了让程序“成功”而关闭定义域检查。

书面结果: 区分下标范围错误、错误数学恒等式与无效输入,按原约定解释各修复。尽管 Python 将布尔值视为整数子类,这里仍明确排除它们作为数量。

13

练习与完整解答

练习 1–12 为必做,约 80 分钟;13–14 为可选拓展,额外约 25 分钟。先写自己的解答,再展开答案。

练习 1★★★概念4 分钟

将 0,−3,5/2,20,-3,5/2,\sqrt{2} 分类到 N,Z,Q,R\mathbb{N},\mathbb{Z},\mathbb{Q},\mathbb{R}。一个数能属于多个数系吗?

查看解答

00 属于四者;−3-3 属于 Z,Q,R\mathbb{Z},\mathbb{Q},\mathbb{R};5/25/2 属于 Q,R\mathbb{Q},\mathbb{R};2\sqrt2 属于 R\mathbb{R},是无理数。数系嵌套,所以成员资格可以重叠。本系列自然数包含零。

练习 2★★★计算4 分钟

计算 −32-3^2、(−3)2(-3)^2、∣−3∣|-3|。解释 Python 赋值 x = x + 1,不要把它当作实数方程。

查看解答

结果为 −9,9,3-9,9,3。第一式的负号在平方外面。赋值先读取右侧旧值,加一,再把结果关联到 x;它不声称旧值等于新值。

练习 3★★★概念4 分钟

0,1/2,1,20,1/2,1,2 中哪些属于 (0,1](0,1]?把一到四的整数下标翻译为 Python 范围。

查看解答

1/21/2 与 11 属于区间;圆括号排除零,二超出上界。使用 range(1,5),因为终点不包含。区间还包括未列出的其他实数。

练习 4★★★计算4 分钟

展开 ∑i=03(2i+1)\sum_{i=0}^3(2i+1) 与 ∏i=13(i+1)\prod_{i=1}^3(i+1)。给出相应空范围的聚合值。

查看解答

和为 1+3+5+7=161+3+5+7=16;积为 2⋅3⋅4=242\cdot3\cdot4=24。空和为零,空积为一。没有项时,不要代入无效末下标。

练习 5★★★推导5 分钟

给定 f(t)=3t−2f(t)=3t-2、g(x)=x2+1g(x)=x^2+1,推导 f(g(x))f(g(x)) 与 g(f(x))g(f(x)),并在 x=2x=2 计算两者。

查看解答

f(g(x))=3(x2+1)−2=3x2+1f(g(x))=3(x^2+1)-2=3x^2+1,取值为 1313。另一顺序为 g(f(x))=(3x−2)2+1=9x2−12x+5g(f(x))=(3x-2)^2+1=9x^2-12x+5,在 x=2x=2 得到 1717。两者均在实数上定义,但不是同一函数。

练习 6★★★推导6 分钟

展开并化简 s(x)=∑i=13(x+i)s(x)=\sum_{i=1}^3(x+i)。指出自由与绑定变量,并安全改名绑定变量。

查看解答

展开得到 (x+1)+(x+2)+(x+3)=3x+6(x+1)+(x+2)+(x+3)=3x+6。xx 自由,ii 被求和绑定。∑k=13(x+k)\sum_{k=1}^3(x+k) 保留含义;∑x=13(x+x)\sum_{x=1}^3(x+x) 会捕获原输入并改变含义。

练习 7★★★推导6 分钟

推导实数函数 f(x)=4x−3f(x)=4x-3 的反函数,验证两个复合方向。解释平方为什么需要限制定义域才能有反函数。

查看解答

由 y=4x−3y=4x-3 解得 f−1(y)=(y+3)/4f^{-1}(y)=(y+3)/4。因此 f−1(f(x))=(4x−3+3)/4=xf^{-1}(f(x))=(4x-3+3)/4=x,f(f−1(y))=4(y+3)/4−3=yf(f^{-1}(y))=4(y+3)/4-3=y。实数平方把 22、−2-2 都映到 44,不能唯一恢复输入。将其定义域与陪域限制为非负实数后,反函数为平方根。

练习 8★★★计算8 分钟

按行与按列计算 ∑i=12∑j=13(10i+j)\sum_{i=1}^2\sum_{j=1}^3(10i+j)。解释为什么不能直接对 ∑i=13∑j=1ij\sum_{i=1}^3\sum_{j=1}^i j 使用相同的交换论证。

查看解答

行总和为 3636、6666,整体 102102;列总和为 32,34,3632,34,36,整体仍为 102102。有限矩形的六个下标对在两种次序中各出现一次。三角形范围的有效对依赖外层下标,其总和为 1+(1+2)+(1+2+3)=101+(1+2)+(1+2+3)=10;交换时必须保留同一三角形下标集合。

练习 9★★★编程8 分钟

为实数标量函数写约定与代码:x<0x<0 时 h(x)=2x+1h(x)=2x+1,否则为 x2x^2。给出三个检查,包括边界,并描述输出可能的符号。

查看解答

约定:输入输出各为一个实数标量,不修改输入。实现:

def h(x):
    if x < 0:
        return 2 * x + 1
    return x * x

检查 h(−2)=−3h(-2)=-3、h(0)=0h(0)=0、h(3)=9h(3)=9。负输入分支可以产生负值、零或正值:x=−1,−1/2,−1/4x=-1,-1/2,-1/4 时分别输出 −1,0,1/2-1,0,1/2。另一分支产生非负值。输入符号不能单独确定第一分支结果的符号。

练习 10★★★概念8 分钟

令 f(t)=ln⁡(t−1)f(t)=\ln(t-1)、g(x)=x2g(x)=x^2。给出复合定义域,在 x=−2,0,2x=-2,0,2 计算。如果陪域声明为 R\mathbb{R},每个实输出都能达到吗?

查看解答

要求 x2−1>0x^2-1>0,定义域为 (−∞,−1)∪(1,∞)(-\infty,-1)\cup(1,\infty)。−2-2 与 22 输出 ln⁡3\ln3,零处未定义。任意实数 yy 都可达到:取 x=ey+1>1x=\sqrt{e^y+1}>1,则 ln⁡(x2−1)=y\ln(x^2-1)=y。此例像等于陪域,但这是需要论证的性质,并非所有函数都如此。

练习 11★★★编程11 分钟

开发者用 range(1,n) 计算前 nn 个正奇数之和。找最小正反例、修复,并说明无效输入处理。

查看解答

n=1n=1 时,范围为空,错误返回零而非一。使用 range(n) 配项 2*i+1,或 range(1,n+1) 配项 2*i-1。要求非负整数,清楚拒绝负数与非整数;若排除布尔值,必须明确检查,因为 Python 的 bool 是 int 子类。修复后检查零、一及较大数量。

练习 12★★★概念12 分钟

诊断“每个函数都分配到加法上”与“正输入满足 ln⁡(a+b)=ln⁡a+ln⁡b\ln(a+b)=\ln a+\ln b”。提供有效反例,解释为什么成功检查不能证明全称主张。

查看解答

第一条取 f(x)=x2f(x)=x^2、a=2a=2、b=3b=3,得到 25≠1325\ne13。第二条取 a=b=1a=b=1,得到 ln⁡2≠0\ln2\ne0。所有表达式均在有效定义域内。一个矛盾输入足以否定全称陈述;有限成功案例仍留下其他输入未检查。正确对数恒等式涉及乘积而非和。

练习 13★★★推导10 分钟

可选:利用逆序有限求和推导 ∑i=0n−1(2i+1)=n2\sum_{i=0}^{n-1}(2i+1)=n^2,包括 n=0n=0。

查看解答

n>0n>0 时,令 A=0+1+⋯+(n−1)A=0+1+\cdots+(n-1),逆序后逐项相加。每个配对项为 n−1n-1,共有 nn 个,因此 2A=n(n−1)2A=n(n-1)。于是 ∑(2i+1)=2A+n=n(n−1)+n=n2\sum(2i+1)=2A+n=n(n-1)+n=n^2。n=0n=0 时,两侧都为零。该论证覆盖整个定义域,而非仅观察到的例子。

练习 14★★★推导15 分钟

可选:正确交换 ∑i=1n∑j=1ij\sum_{i=1}^n\sum_{j=1}^i j 的求和顺序,给出新界,并验证 n=3n=3。

查看解答

有效下标对满足 1≤j≤i≤n1\le j\le i\le n。先固定 jj 后,ii 从 jj 到 nn,因此等价表达式为 ∑j=1n∑i=jnj=∑j=1n(n−j+1)j\sum_{j=1}^n\sum_{i=j}^n j=\sum_{j=1}^n(n-j+1)j。n=3n=3 时为 3⋅1+2⋅2+1⋅3=103\cdot1+2\cdot2+1\cdot3=10。下标对的描述解释了边界为什么改变。

14

自测题

九道选择题自动检查。第 10 题需要解释,请与参考答案比较并自评。自动得分只涉及九道选择题。书面回答与复核标记会和时段进度一样保存在当前浏览器。

1
按本系列约定,零是自然数吗?
2
Python 的 range(1,5) 产生什么?
3
实数平方函数的像是什么?
4
若 f(t)=2t+1f(t)=2t+1、g(t)=t2g(t)=t^2,f(g(3))f(g(3)) 是多少?
5
ln⁡(x−1)\ln(x-1) 的实数定义域是什么?
6
对正数 a,ba,b,哪个恒等式普遍成立?
7
空积是什么?
8
∑i=13(x+i)\sum_{i=1}^3(x+i) 中哪个变量仍然自由?
9
一个全称恒等式通过十个输入检查,说明什么?
查看答案

对于 f(t)=1/(t−2)f(t)=1/(t-2)、g(x)=x+1g(x)=x+1,每个实数 xx 都是有效内层输入,但 x=1x=1 产生 g(1)=2g(1)=2,不属于外层定义域。复合为 1/(x−1)1/(x-1),定义域为 R∖{1}\mathbb{R}\setminus\{1\}。只有明确解释中间失败与结果定义域,才给书面题这一分;其他正确例子也可。

15

引导阅读

必读,10 分钟: 使用 MIT 计算机科学数学 的函数材料。阅读其链接教材中函数、定义域与陪域的定义,暂不继续关系与证明内容。写一个陪域有未使用值的映射,解释为什么仍是函数。

必读,15 分钟: 配合下方记法总结,阅读 机器学习数学 的数学语言与记法介绍。找一个有限带下标表达式,说明各符号角色,并展开三项实例。这里只预览书中记法,不要求已经理解后续线性代数。

可选: 比较代码与记法时,阅读官方 Python range 例子 与 对数文档。涉及行为差异时,使用匹配本地解释器版本的文档。本模块数学说明与练习为原创,外部资源供进一步阅读。

16

复习与逻辑模块准备

思想链条是:声明对象与允许值,明确运算,检查定义域,展开小例子,翻译作用范围与下标,再用有效论证检验主张。函数的像是实际达到的输出,陪域是声明目标集合。有限求和绑定其下标,其他输入可能仍然自由。

结业任务: 为练习 9 的分段函数写规格与 Python 实现,展开一个小双重求和,并在有效输入上否定对数加法恒等式。不要只复述答案,应能自己解释。课程建议评分为书面练习 60 分、实验解释 30 分、自测 10 分,其中包括复核后的书面回答。

模块 02 精确说明“每个”“存在”“如果”“只有当”等表达。开始前应能解释定义与关于全部输入的主张之间的区别。保留本模块反例,它是逻辑推理的起点。

17

记法与双语术语

符号或英文术语 含义 中文
Domain 允许输入 定义域
Codomain 声明目标集合 陪域
Image 实际达到的输出 像
Composition f∘gf\circ g 先 g 后 f 复合函数
Inverse f−1f^{-1} 唯一逆转映射 反函数
∈\in / ⊆\subseteq 成员资格 / 集合包含 属于 / 包含于
[a,b)[a,b) 包含 a,排除 b 左闭右开区间
∑\sum / ∏\prod 和 / 积 求和 / 乘积
Bound / free variable 受作用域限制的下标 / 保留输入 绑定变量 / 自由变量
Definition / assumption / claim 含义 / 环境 / 待建立陈述 定义 / 假设 / 主张
Counterexample 否定全称主张的有效案例 反例
Contract 允许输入与保证结果 约定