简介:这份资源是 Timothy Sauer《Numerical Analysis》第三版(Pearson 2018)的官方教师解答手册,面向正在学习数值分析课程的高校本科生、研究生及授课教师,用于核对课后习题答案、理解算法推导过程。手册按教材章节组织,覆盖多项式求值、二分法与不动点迭代、精度极限、牛顿法、高斯消元与LU分解、插值误差与切比雪夫插值、样条与贝塞尔曲线、最小二乘与QR分解、数值微分与龙贝格积分、常微分方程初值问题及龙格-库塔方法、边值问题与有限元等内容,配合教材使用可对照验证每一步计算结果与误差分析思路。整包为1个PDF文件,约6.75MB,便于在电脑或平板上直接检索与批注。目前已有3381人学习下载,适合需要系统练习、核对答案与查漏补缺的读者。
1. 数值分析第三版答案到底是什么:一份能看见推导过程的参照
很多人第一次搜“数值分析 答案 第三版”,是在作业本上卡住的晚上:方法明明看懂了,算出来的数却和书后对不上。这份东西的本质,是一份把中间步骤展开给你看的解题参照。数值分析这门课研究的不是求一个漂亮的解析式,而是“计算机怎么一步步逼近一个足够好的近似值”——二分法怎么缩区间、牛顿法怎么用切线找零点、误差项怎么估、收敛阶从哪来。教材正文负责讲方法,答案手册补的是每一步具体代入了什么数、迭代了几轮、误差落在什么量级。搞清这个定位,你才知道该拿它对照思路,而不是抄最后一行。
2. 为什么会有“答案手册”这种东西:从“算得出”到“算得对”
2.1 计算机算数学,难在哪
数学里的实数有无限多位,计算机里的浮点数只有有限位。这个矛盾是所有数值方法的起点。你写下一个根号 2,纸面上它是个精确符号;交给计算机,它只能变成 1.4142135623730951 这样一串有限长的近似值。于是每一个数值算法都必须回答三个问题:近似值离真值有多远,这叫误差;多算几步会不会更接近,这叫收敛;算到哪一步该停,这叫停机准则。
举个最朴素的例子。求方程 x² = 2 的正根,解析解是根号 2,写出来就完事。可计算机不会开方,它只会做加减乘除和比较大小,所以得换一条路:先猜一个区间 [1, 2],因为 1²=1 小于 2、2²=4 大于 2,根一定夹在中间;取中点 1.5,平方得 2.25,比 2 大,于是把区间缩到 [1, 1.5];再取中点 1.25……每缩一次,区间长度减半,误差上限也就减半。这套动作重复五十来次,你就能拿到十几位有效数字。
这里藏着一个关键认知:数值分析题目的答案,往往不是一个数字,而是一串中间结果。迭代了几次、每次的误差是多少、误差缩小的速度是线性还是二次、矩阵的条件数有多大,这些东西才构成“算对了”的证据。只盯最后一行数字,你根本不知道自己错在哪一步——是公式抄错了,是初值选偏了,还是本来就该有这个量级的误差。
这也是答案手册存在的第一个理由。数值计算里,“算错”和“算到精度上限”长得非常像:结果都和你心里的标准值有偏差。区分这两者,靠的是看过程,不是看结果。
2.2 答案手册的原始定位:一份给授课者的对照表
这份材料的英文原名是 Instructor's Solutions Manual,直译就是“教师解答手册”。它的封面页写得很清楚:作者和出版方尽力研究、测试了书中的理论与程序,但不对程序的有效性作任何担保,也不承担因使用这些程序造成的连带损失。这段话不是客套,它点明了一件事:手册的定位是教学配套,是给讲课的人快速核对每道题演算路径的参照物。
理解这个定位很要紧。它意味着手册里的解答是“一条可行路径”,不是“唯一正确路径”。同样一道求根题,你用二分法做,他用牛顿法做,中间过程完全不同,最后都收敛到同一个根,误差都落在合理范围里,两个都对。手册给的是其中一条路,你拿自己的过程去对,对的是“思路有没有走偏、误差量级对不对”,而不是“小数点后第八位是不是一模一样”。
手册里还有一类题叫 Computer Problems,配套的是脚本语言写的命令和输出。比如第 0 章有一题,用嵌套乘法算一个 51 次多项式在 x = 1.00001 处的值,命令执行后得到 51.01275208274999,与理论值相差 4.76×10⁻¹²。这类题的答案形态是“命令 + 输出 + 与理论值的偏差”,它要你观察的正是浮点运算累积起来的那点误差,而不是那个数字本身。
所以这份手册写得“啰嗦”是有原因的:数值题的得分点全在过程里。矩阵消元的每一步乘数、换行记录,迭代法的误差序列,插值误差项里那个 n+1 阶导数的上界估计,这些才是能判断你会不会的东西。
2.3 一份答案手册里到底有什么:从第 0 章说起
翻开目录,第 0 章叫 Fundamentals,讲的是多项式求值、二进制数、实数的浮点表示、有效数字丢失、微积分复习。这一章看起来像“预备知识”,实际上是后面所有误差分析的尺子。你不懂浮点数只有 53 位尾数,就看不懂后面为什么牛顿法迭代到某一步就不再变好。
往下走,第 1 章 Solving Equations 是解方程:二分法、不动点迭代、精度极限、牛顿法、不用导数的求根方法。第 2 章 Systems of Equations 是方程组:高斯消元、LU 分解、误差来源、PA=LU 分解、迭代法、对称正定矩阵的特殊方法、非线性方程组。第 3 章 Interpolation 是插值:数据与插值函数、插值误差、切比雪夫插值、三次样条、贝塞尔曲线。第 4 章 Least Squares 是最小二乘:正规方程、模型综述、QR 分解、GMRES、非线性最小二乘。
再往后,第 5 章是数值微分与积分,从牛顿-科茨公式一路讲到龙贝格积分、自适应求积、高斯求积。第 6 章是常微分方程初值问题:解的存在性分析、方程组、龙格-库塔、变步长、隐式方法与刚性方程、多步法。第 7 章边值问题:打靶法、有限差分、配点与有限元。第 8 章偏微分方程:抛物型、双曲型、椭圆型、非线性。第 9 章随机数与蒙特卡洛,第 10 章三角插值与快速傅里叶变换,第 11 章压缩(离散余弦变换、图像压缩、哈夫曼编码、音频压缩),第 12 章特征值与奇异值(幂迭代、QR 算法、SVD),第 13 章优化。
这份结构本身就是一张知识地图。它告诉你:数值分析的每一章都包含三样东西——方法的构造、方法的误差分析、方法在计算机上的实际表现。答案手册对这三样都有对应,所以你翻答案时不能只看“结果对不对”,还要看“它有没有给出误差估计”和“它有没有讨论这个方法什么时候会失效”。
拿多项式求值来说,第 0 章第一节讲的是把多项式改写成嵌套形式。原式 P(x) = 6x⁴ + x³ + 5x² + x + 1,改写成 P(x) = 1 + x(1 + x(5 + x(1 + x·6))),乘法次数从十几次降到四次。这就是为什么数值分析里到处都是这种“改写”:
# 秦九韶(Horner)法则:把多项式写成嵌套形式,减少乘法次数 def horner(coeffs, x): # coeffs 按从最高次到常数项排列,例如 [6, 1, 5, 1, 1] 表示 6x^4 + x^3 + 5x^2 + x + 1 result = coeffs[0] for c in coeffs[1:]: result = result * x + c # 每轮做一次乘法一次加法,而不是重新算幂 return result print(horner([6, 1, 5, 1, 1], 1/3)) # 输出 2.0,和直接代入的结果一致这段代码的关键参数只有一个 coeffs,顺序不能乱:从最高次项系数排到常数项。x 是代入点。函数返回的是多项式的值。它之所以出现在答案手册的第一页,是因为“少做运算”本身就是一种降低误差的手段——每多一次浮点乘法,就多一次舍入。答案手册在这里给的不是一个数,而是一种习惯。
3. 从求根到特征值:答案手册覆盖的知识地图
3.1 解方程与方程组:误差从哪里冒出来
解方程这一章的核心问题是:给你一个函数 f(x),找它等于零的点。二分法是最稳的,只要区间两端函数值异号,它就一定能收敛,代价是慢——每迭代一次,区间长度减半,误差也减半,这叫线性收敛。牛顿法快得多,它用当前点的切线去和 x 轴相交,把交点当作下一个猜测,收敛速度是二次的:误差每次平方,有效数字位数翻倍。但快是有代价的,牛顿法要求你能算出导数,而且初值不能离根太远,否则切线可能把你甩到很远的地方,甚至直接发散。
这中间的取舍就是答案手册反复展示的东西。你去看牛顿法的解答,会发现它往往只迭代四五次就给出十几位精度;你再看二分法的解答,会发现它老老实实列了二三十行区间。这不是作者偏心,是两种方法的收敛阶摆在那里。答案手册把这两个过程并排放在一起,就是要你亲眼看到“线性”和“二次”在数字上的差距。
方程组那一章同理。高斯消元法的运算量是 O(n³),n 是未知数个数,一千个未知数就是十亿次运算。LU 分解的价值在于复用:同一个系数矩阵、不同的右端项,分解一次可以反复用。PA=LU 分解里的 P 是置换矩阵,作用是在消元过程中交换行,避免主元位置上出现零或者极小的数——这一步不做,程序就会在某个看起来很正常的矩阵上突然出错。答案手册里那些带换行记录的矩阵,演示的就是这个“后悔药”机制。
还有一个容易被忽略的点:误差来源。第 2 章专门有一节叫 Sources of Error,讲的是同一个算法,为什么在有些矩阵上算得准、有些矩阵上算得离谱。答案是条件数。条件数大的矩阵,输入上一点点扰动会被放大成输出上的巨大偏差,这跟算法写得好不好没关系,是问题本身“病”了。答案手册里的数值例子会让你看到:同一个消元程序,条件数小的矩阵误差在 10⁻¹⁵ 量级,条件数大的矩阵误差能到 10⁻³。
def bisect(f, a, b, tol=1e-10, max_iter=100): # 前提:f(a) 与 f(b) 异号,保证区间内至少有一个根 fa, fb = f(a), f(b) if fa * fb > 0: raise ValueError("区间端点同号,二分法不适用") for k in range(max_iter): m = (a + b) / 2 # 取中点 fm = f(m) if abs(fm) < tol or (b - a) / 2 < tol: # 函数值够小,或区间够窄 return m, k + 1 if fa * fm < 0: # 根在左半区间 b, fb = m, fm else: # 根在右半区间 a, fa = m, fm return (a + b) / 2, max_iter root, steps = bisect(lambda x: x * x - 2, 1, 2) print(root, steps) # 约 1.4142135623,迭代约 34 次这里的 tol 控制精度,max_iter 是保险丝,防止死循环。steps 这个返回值很重要:答案手册里二分法的解答通常会把迭代次数标出来,因为次数直接对应误差上界——区间初始长度除以 2 的 k 次方,就是第 k 步的误差上限。你拿自己算的次数和手册里的次数一比,就知道有没有多跑或者少跑。
3.2 插值与最小二乘:为什么答案常有两套写法
插值要解决的问题是:给你若干个数据点,找一个函数穿过它们,好去估计中间位置的值。最直接的想法是多项式插值,n+1 个点能唯一确定一个 n 次多项式。理论上很漂亮,实际用起来有个坑:点数多了,多项式次数就高,高次多项式会在区间两端剧烈摆动,这叫龙格现象。答案手册在第 3 章用切比雪夫节点来对付它——把插值点从均匀分布改成往两端加密的分布,摆动就被压下去了。另一条路是三次样条:不用一个高次多项式,而是用一段段三次多项式拼起来,在拼接点上保证函数值、一阶导、二阶导都连续,曲线光滑,也不会乱摆。
最小二乘解决的是另一类问题:数据点有噪声,你不想让曲线穿过每一个点,只想让它整体上离所有点最近。数学上就是最小化误差平方和,求导之后得到正规方程 AᵀAx = Aᵀb。这里有个数值上的陷阱:AᵀA 的条件数是 A 的条件数的平方。A 的条件数本来是一百,平方就是一万,精度直接掉一半。所以实际计算更常用 QR 分解,先把它拆成一个正交矩阵乘一个上三角矩阵,再解方程,条件数不会被平方放大。
这就解释了一个现象:同一道最小二乘题,答案手册可能给出两个略有差异的结果。不是它算错了,是它分别演示了正规方程解法和 QR 解法,让你看到两者在数值上的差别。你对着自己的答案时,得先搞清楚自己走的是哪条路,再判断偏差是否合理。
3.3 微分方程与信号处理:答案的形态变了
到了常微分方程这一章,答案的形态又变了。前面几章的答案是一个数或者一组数,这里答案是一张表:步长 h 取多少、每一步的近似值、和精确解的差、误差随 h 缩小的速率。第 6 章讲初值问题,欧拉法是一阶的,步长减半误差也减半;龙格-库塔四阶法的误差和 h⁴ 成正比,步长减半误差降到十六分之一。答案手册里的表格就是让你验证这个“阶”对不对。
刚性方程是个分水岭。所谓刚性,就是方程里同时存在变化极快和极慢的分量,显式方法为了稳定性被迫把步长压到极小,算到天荒地老。这时候必须换隐式方法,每一步都要解一个方程,单步成本高,但步长可以放大很多。答案手册在 6.6 节专门处理这类问题,给的解答里会明确标注用的是显式还是隐式格式,因为用错了格式,结果会直接崩掉。
再往后,偏微分方程、快速傅里叶变换、图像与音频压缩、特征值分解,每一章的答案都带着自己的“验证形式”:偏微分方程看稳定性条件,傅里叶变换看频域结果,压缩看重建误差,特征值看残差范数。这也是为什么这份手册不能当“对答案工具”用——不同章节的正确性标准根本不是一个东西。
4. 常见误区与易混概念:答案、解析解、代码实现不是一回事
4.1 误区一:答案只有一个数,对不上就是自己做错了
易混点在于把数值答案当成唯一解。数值方法算出来的永远是近似值,误差只要在方法本身的收敛阶允许范围内,就是对的。你用的是牛顿法,迭代四次得到 1.41421356237,手册上写 1.4142135623730951,两者差在第十一位,这不是错,是收敛到那一步的正常表现。
为什么容易混?因为从小学到高中的数学题,答案都是精确的、唯一的,1+1 只能等于 2。到了数值分析,正确性变成了一个区间概念。
怎么区分?看两件事:一是误差量级是否和方法匹配,二分法迭代三十次就不该指望十五位精度;二是看手册有没有给出误差估计,如果它给了上界,你就拿自己的结果去比上界,而不是比数字。
4.2 误区二:数值解和解析解是一回事,只是精度不同
易混点在于两个词都叫“解”。解析解是符号表达式,比如根号 2、π、e^{-x};数值解是一串浮点数。它们不是“同一个东西的粗略版和精确版”,而是两种性质不同的对象。
为什么容易混?因为很多时候数值解确实在逼近解析解,看起来只是“不够精确”。但有些问题根本没有解析解,比如大多数非线性微分方程、五次以上的多项式方程、复杂的积分。这时候数值解不是退而求其次,它是唯一可得的答案。
怎么区分?问自己一句:这个结果能不能写成闭式表达式?能,解析解优先;不能,或者闭式表达式复杂到没法算,数值解就是正解。答案手册里两类都会出现,你看它给的是公式还是数字,就知道这道题在训练什么。
4.3 误区三:误差就是算错了
易混点在于中文里“误差”和“错误”都带个“误”字。数值分析里的误差是中性词,指近似值和真值之间的差距,它有来源、有量级、有传播规律。算错了是人为失误,公式抄反了、循环写错了、单位没统一。
为什么容易混?因为两者表现出来的样子一样:结果和预期不符。
怎么区分?做一次收敛性检查。把步长减半、把迭代次数加倍,如果误差按理论速率下降,说明方法在正常工作,剩下的偏差是截断误差和舍入误差;如果误差不降反升,或者乱跳,那才是真出问题了。答案手册里的误差分析段落,本质上就是在教你做这个判断。
4.4 误区四:收敛和稳定是同义词
易混点在于两个词经常一起出现,听起来都是“方法表现良好”。收敛说的是迭代序列会不会趋向真解;稳定说的是计算过程中误差会不会被放大。一个方法可以收敛但不稳定,也可以稳定但收敛得极慢。
为什么容易混?因为教材里经常写“该方法收敛且稳定”,一句话带过,读者就默认它们是同一件事。
怎么区分?收敛看极限,稳定看扰动。举个例子,显式欧拉法解某些刚性方程,理论上是收敛的,步长趋于零时解确实趋近真解,但实际计算时步长稍大就爆掉,这就是稳定性条件在限制你。答案手册里凡是出现“稳定性条件”“步长限制”的地方,讲的都是稳定,不是收敛。
4.5 误区五:答案里的代码可以直接拿去交作业或者上生产
易混点在于手册里确实有代码,有命令,有输出。但它们是为教学写的,不是为工程写的。
为什么容易混?因为代码能跑通,输出看着也对。
怎么区分?看三样东西:有没有异常处理,有没有参数校验,有没有考虑边界情况。教学代码通常假设输入是良态的,工程代码必须假设输入是恶意的。手册里一个求根函数可能只有十行,生产环境里同样的功能要考虑区间端点同号、函数值溢出、迭代不收敛、精度达不到要求这四种情况。把它当参考实现看没问题,当交付物用就会踩坑。
5. 答案里的“过程”怎么读:以浮点数与误差为例
5.1 浮点表示:为什么 0.1 存进去就不是 0.1 了
第 0 章用不小的篇幅讲二进制和浮点表示,原因很简单:计算机存不下 0.1。十进制里的 0.1,转成二进制是 0.00011001100110011……无限循环,和十进制里的 1/3 一样。双精度浮点数只有 53 位尾数,只能截断到某一位,存进去的其实是一个极其接近但不等于 0.1 的数。
print(0.1 + 0.2) # 输出 0.30000000000000004 print(0.1 + 0.2 == 0.3) # 输出 False这不是程序有 bug,是浮点表示的必然结果。两个近似值相加,误差累积起来,最后那一位就对不上了。答案手册里凡是出现 0.30000000000000004 这种数字,都不是排版错误,是它在诚实地展示浮点运算的样子。
双精度的机器精度大约是 2.2×10⁻¹⁶,意思是 1 加上比这个更小的数,结果还是 1。这个数字决定了所有迭代方法的下限:你再怎么优化算法,误差也不可能低于这个量级。
5.2 有效数字丢失:一次减法如何吃掉精度
比舍入误差更隐蔽的是有效数字丢失。两个很接近的数相减,结果的绝对误差不变,但相对误差会被急剧放大。比如 1.000000000000001 减去 1,结果是 10⁻¹⁵ 量级,可这个结果里只剩下一位有效数字了,因为参与运算的两个数各自都只精确到 10⁻¹⁶。
第 0 章第 4 节 Loss of Significance 专门讲这个。典型例子是计算 1 + 2⁻⁵¹ + 2⁻⁵³ 再减 1:按双精度的舍入规则,中间那个和会被舍入到 1 + 2⁻⁵¹,减完 1 之后剩下 2⁻⁵¹,而理论上应该是 2⁻⁵¹ + 2⁻⁵³,尾数的那一小截被吃掉了。
对付它的办法是改写公式。求根公式里 b² 远大于 4ac 的时候,两个根一个正常、一个因为相减丢精度,这时候把那个根改写成 c/(a·x₁) 的形式,用乘法代替减法,精度就回来了。答案手册在数值微分、方差计算这些地方会反复用到这类改写,你对着看的时候要留意它为什么换了写法,而不是只看换完之后的数字。
5.3 迭代收敛速度:答案里的表格在说什么
答案手册里最值得看的是那种“迭代次数 vs 误差”的小表格。它其实在告诉你方法的收敛阶。线性收敛的表格,误差每一行大约缩小同一个倍数,比如每次都乘 0.5;二次收敛的表格,误差的指数在翻倍,这一行是 10⁻³,下一行就是 10⁻⁶,再下一行 10⁻¹²。
牛顿法就是典型的二次收敛:
def newton(f, df, x0, tol=1e-12, max_iter=50): x = x0 for k in range(max_iter): fx = f(x) if abs(fx) < tol: # 函数值足够接近零,认为已收敛 return x, k x = x - fx / df(x) # 沿切线方向走到与 x 轴的交点 return x, max_iter root, steps = newton(lambda x: x * x - 2, lambda x: 2 * x, 1.0) print(root, steps) # 约 1.4142135623730951,约 6 次迭代x0 是初值,tol 是停机阈值,max_iter 防止发散时死循环。d f 必须由你提供,这是牛顿法最现实的门槛:很多函数手写导数很麻烦,写错了整个迭代就废了。答案手册里凡是牛顿法的题,导数都会单独列出来,你可以拿它对照自己求的导。
看到误差不是按平方缩小,而是按固定倍数缩小,就说明你可能把牛顿法写成了割线法,或者初值离根太远、还没进入二次收敛的区域。这张表比最终答案有用得多。
6. 什么时候该用它,什么时候别碰:一份使用边界清单
这份手册的价值集中在“对照过程”,不在“提供结果”。把它放在合适的位置上,它就是个好东西;放错位置,容易让人产生“我学会了”的错觉。
| 使用场景 | 适合程度 | 原因 |
|---|---|---|
| 做完题后核对中间步骤 | 适合 | 能看出自己在哪一步走了弯路,误差量级是否合理 |
| 验证自己写的算法输出 | 适合 | 手册给的误差分析和收敛阶可以直接当基准 |
| 理解某个方法的失效条件 | 适合 | 每章都有专门的误差来源与稳定性讨论 |
| 只想抄最后一行数字交作业 | 不适合 | 数值题的过程分远大于结果分,抄了也学不到东西 |
| 直接把示例代码放进项目 | 不适合 | 缺少输入校验、异常处理和性能考虑 |
| 代替教材正文学习 | 不适合 | 手册假设你已经读过方法推导,它只补演算细节 |
适合的场景有一个共同点:你已经有自己的思路和结果,需要一个参照物来判断对错。不适合的场景也有一个共同点:你想跳过思考,直接拿到一个可以交出去的东西。
我自己有过一次挺典型的翻车。当时用迭代法解一个线性方程组,跑出来的结果和手册对不上,差得不算离谱但也不在误差范围内。第一反应是手册印错了,第二反应是代码写错了,折腾了一下午,最后发现问题出在初值上——我随手给的初始向量离真解太远,迭代次数不够,压根没收敛。从那以后我每次跑数值实验前都强制走一遍固定动作:先打印误差序列看它有没有在稳定下降,再检查矩阵条件数,最后才去和答案手册的前两步对照。顺序一换,很多“玄学”问题就变成了可以定位的工程问题。
所以这份东西最适合放在手边当参照物,而不是当拐杖。你先自己算,算完再翻,翻的时候重点看过程而不是结果;卡住的时候看它怎么处理边界情况、怎么估计误差、怎么判断收敛。真要把数值方法用熟,靠的还是自己动手把每一步跑一遍。希望帮到你。
本文还有配套的精品资源,点击获取