怎样把有根证明变成误差可证的算法?¶
先备知识¶
零点定理、闭区间与 Python 函数调用。算法源码唯一位于
src/mathbook_examples/bisection.py。
学习目标¶
从连续异号条件导出二分不变量、误差界和停止准则,并解释实现拒绝的输入。
牵引问题¶
怎样返回一个数,并证明它离区间中的某个真根不超过给定容差?
探索与猜想¶
保留异号半区间就保留至少一个根;区间长度每步减半,中点到区间内任意根至多为半长。
概念与理论¶
算法:认证二分法¶
输入连续 \(f\)、有限端点 \(a<b\)、\(f(a)f(b)\le0\)、容差 \(\tau>0\)。若端点是根立即返回;否则反复取安全中点 [ m=a+\frac{b-a}{2}, ] 若命中根则返回,否则保留仍异号的一半,直到区间半长不超过 \(\tau\)。
循环不变量是: [ a_n<b_n,\quad f(a_n)f(b_n)\le0,\quad [a_n,b_n]\text{ 至少含一个根}. ]
定理:二分误差证书¶
完成 \(n\) 次二分后,区间长度为 \((b-a)/2^n\)。若返回其中点 \(r_n\),则对 该区间中的某个根 \(c\), [ |r_n-c|\le\frac{b-a}{2^{n+1}}. ] 要使误差不超过 \(\tau\),选择满足 [ 2^{n+1}\ge\frac{b-a}{\tau} ] 的步数。证明只用根仍在区间内以及中点到区间内任一点不超过半长。\(\square\)
小残差 \(|f(r)|\) 不是无条件的根误差界;函数可能非常平坦。
例题与迁移¶
例题1:调用唯一实现¶
from mathbook_examples.bisection import bisect
result = bisect(lambda x: x**3 + x - 1, 0.0, 1.0, tolerance=1e-6)
print(result.root, result.error_bound)
error_bound 来自最终有根区间,不依赖已知“标准答案”。
例题2:先验步数¶
初始长度为1,要中点误差不超过 \(10^{-6}\),取满足 \(2^{n+1}\ge10^6\) 的最小 \(n\)。实现还需给足迭代预算。
即时检验与回望¶
检验1:为什么保留异号?¶
答案
它使零点定理每一步都可再次应用,保证根不被丢弃。
检验2:端点为根怎么办?¶
答案
立即返回该端点,误差界为零,不必二分。
习题与答案¶
习题1¶
初始长度1,20次二分后中点误差界是多少?
答案
\(2^{-21}\)。
习题2¶
二分法保证根唯一吗?
答案
不保证,只保证最终区间至少含一个根。
习题3¶
端点同号能否直接运行?
答案
不能;缺少零点存在证书,即使区间内部偶然有偶数个根也无法由此合同确认。
习题4¶
为何容差必须为正且有限?
答案
非正容差不能形成可达停止条件,非有限值不能表达有效误差目标。
习题5¶
为什么拒绝函数返回 NaN?
答案
NaN 无法比较符号,会破坏异号不变量与分支判断。
常见误区与后续¶
二分误差是区间证书,不是残差猜测;算法需要连续性、异号、有限输入、正容差和足够 预算。下一单元统一比较三类证书。