本节摘要:微积分诞生于几何直觉(切线、面积),但"无穷小"的模糊地位让它背负两百年逻辑债务,直到柯西与魏尔斯特拉斯用 epsilon-delta 语言把极限改写成静态不等式。本节讲清极限定义的读法、导数作为局部线性近似、定积分作为黎曼和极限、微积分基本定理为何深刻,最后演示一致收敛被忽略时的经典翻车。全程配 SymPy 符号演算与数值实验。
牛顿与莱布尼茨的微积分立刻就能算出行星轨道、炮弹轨迹,但它的地基是"无穷小量"——一个时而被当非零数参与除法、时而又被大方扔掉的怪东西。贝克莱主教的挖苦流传至今:"消失量的幽灵"。债拖到十九世纪才由柯西与魏尔斯特拉斯还清:不再说"无穷小是多少",改说"对任意 epsilon 大于零,存在 delta 大于零,使得……"——把动态的"趋于"翻译成静态的可验证不等式。这次改造的意义怎么强调都不过分:从此"极限"从一个模糊动词变成一个可以严格证明的对象,整个现代分析(实分析、泛函、测度论)都建在这套语言上。
极限定义的读法要过关:说函数 f 在点 a 的极限为 L,意思是无论你提出多小的误差带宽 epsilon,我都能找到一个接近范围 delta,使 x 落在这个范围内时 f 与 L 的偏差被压进带宽。任意是挑战,存在是应战。用数值实验体验这一定义的"可执行性":
def limit_verified(f, a, L, epsilons=(0.1, 0.01, 1e-3, 1e-4)): # 对每个 epsilon 挑战,搜索一个 delta 应战:|x-a|<delta 时 |f(x)-L|<epsilon for eps in epsilons: delta = 1.0 while delta > 1e-12: ok = all(abs(f(a + h) - L) < eps for h in [delta * t for t in (-0.9, -0.5, 0.5, 0.9)]) if ok: print(f"epsilon={eps:.0e} -> delta={delta:.0e} 应战成功") break delta /= 2 import math limit_verified(lambda x: (x**2 - 1) / (x - 1), 1, 2) # x 趋于 1 时该分式趋于 2(x 不等于 1 时分式等于 x+1); # 每个 epsilon 都能找到 delta——这就是"极限为 2"的可执行含义
导数的几何意义是切线斜率,但更实用的解读是"局部线性近似":好的函数在小范围内近似一条直线,斜率就是导数。物理、经济、机器学习里的"灵敏度分析"全是这个视角。严格定义是差商的极限,可导必连续,反之不然——绝对值函数在零点连续但左右斜率不同,是标准反例;魏尔斯特拉斯更进一步造出处处连续处处不可导的函数,彻底粉碎"连续函数总归光滑"的直觉。
import sympy as sp x = sp.symbols('x') f = x**3 - 2*x + 1 df = sp.diff(f, x) print(df) # 3*x**2 - 2:幂函数逐项求导 # 局部线性近似的质量检验:在 a=1 处的切线与原函数的偏差 a = 1 tangent = f.subs(x, a) + df.subs(x, a) * (x - a) for h in [0.5, 0.1, 0.01]: err = abs(float(f.subs(x, a + h) - tangent.subs(x, a + h))) print(f"h={h:<5} 偏差={err:.2e}") # 输出偏差按 h 的平方速度缩小:一阶近似的误差是二阶小量——泰勒展开的第一课
泰勒展开把局部线性近似升级成局部多项式近似,是整套数值方法(第 5 章)的理论底座:欧拉法、牛顿迭代、最优化梯度法,全是泰勒展开不同阶数的取用。
面积问题比切线问题更古老(阿基米德穷竭法已算抛物线弓形面积)。黎曼的方案:把区间切成小段,每段用矩形近似,求和取极限——定积分就是黎曼和的极限。用程序把"取极限"演成"加密网格":
def riemann_sum(f, a, b, n, sample="mid"): # 黎曼和:n 个矩形,采样点取左端、右端或中点 dx = (b - a) / n total = 0.0 for i in range(n): if sample == "left": x_i = a + i * dx elif sample == "right": x_i = a + (i + 1) * dx else: x_i = a + (i + 0.5) * dx total += f(x_i) * dx return total import math f = lambda t: math.exp(-t*t) # 高斯函数,原函数不是初等函数 for n in [10, 100, 1000, 10000]: print(n, riemann_sum(f, 0, 1, n)) # 输出收敛到 0.7468241...(即根号 pi 除 2 乘误差函数值) # 左端点与右端点单调夹逼,中点法收敛更快——数值积分的种子(第 5 章)
微分与积分起初是两个独立问题(切线 vs 面积),牛顿—莱布尼茨定理说它们互为逆运算:变上限积分的导数是被积函数本身。这让"求面积"从逐个极限的苦役变成"找原函数代人两端点"的查表工作。工程意义巨大:能量是力的积分、路程是速度的积分、概率是密度的积分,而边际量反方向求导即得。这座桥的存在,使整个物理学的表述格式变成"微分方程加初始条件"(第 5 章主角)。
初学者的常见幻觉是"极限可以随便交换次序"。反例来自连续函数的极限:一列处处连续的函数,逐点收敛到的函数可以不连续——只有一致收敛(delta 不依赖点)才保住连续性与可导性。历史上傅里叶级数的逐项积分、微分合法性之争持续了大半个世纪,最终以一致收敛等充分条件收场。这个教训的数值版本:
# 连续函数列逐点收敛到不连续函数:f_n(x) = x^n 在 [0,1] 上 import numpy as np xs = np.linspace(0, 1, 201) for n in [2, 5, 20, 100]: vals = xs ** n jump = vals[-2] # 接近 1 处的函数值 print(f"n={n:<4} 在 x=0.995 处取值 {jump:.4f}") # n 增大时,[0,1) 内部趋于 0 而 x=1 处恒为 1——极限函数在 1 处跳变 # 逐点极限不连续:不一致收敛的活体标本,交换极限与求值次序要付出代价
⚠️ 实用警告:数值求导是病态问题。中心差分公式 (f(x+h) 减 f(x-h)) 除以 2h 的截断误差随 h 缩小而减小,但浮点相减的舍入误差随 h 缩小而放大——h 取约等于机器精度三分之一次方的量级最优。别在数值代码里直接用极小 h。
分析的严格化告一段落,下一节把这套工具装到复平面与频率轴上——傅里叶分析与复分析,现代工程的左右手。