
简介北京理工大学2009级计算机学院《数值分析》期末试卷及部分答案PDF面向需要系统复习数值分析课程、备战期末考试的高校理工科学生。试卷覆盖数值解法、插值法、迭代法与线性方程组求解等核心内容题型包括填空、判断和计算并从有效数字、范数计算、牛顿下山法、松弛迭代、样条插值等细节入手能够帮助学习者快速定位知识薄弱点。资源压缩包内为单个PDF文件体积约91KB便于下载后打印或移动端阅读。目前已有259人学习使用。除完整试卷题目外内容预览中还包含部分填空题答案与提示对考生核对基本概念、掌握标准求解步骤有直接参考价值配合教材与课堂笔记使用可在考前完成一轮高效自测与查漏补缺提升解题熟练度。1. 这份2009级数值分析试卷比想象中更适合拿来复习数值分析这门课最尴尬的场景是教材翻完了、公式也背了一到手算题还是不知道从哪一步开始。北京理工大学2009级计算机学院的这份期末试卷A卷恰好把数值分析最核心的几块——有效数字与误差估计、插值法、迭代法收敛性、线性方程组直接解法——全部浓缩在20道填空、10道判断和6道计算题里。更难得的是这份资源附带了完整答案连列主元消元的每一步换行和消去系数都写得清清楚楚。对于正在备考、或者工作后想快速捡起数值方法的开发者来说这份试卷相当于一份带标准解的练习题集可以直接用来检验自己对收敛条件、差商表和迭代格式的理解是否到位。下文按照试卷的考察顺序把每类题背后的原理、手算步骤和Python验证方法展开讲。2. 有效数字与误差估计填空题前几题其实在考同一个概念2.1 有效数字的判定从0.231与0.229说起试卷第一题给出x0.231是精确值x*0.229的近似值问x有几位有效数字。答案写的是2位。很多人会疑惑0.231有三位数字为什么只有两位有效这里的关键在于有效数字的定义如果近似值x的绝对误差不超过其某一位上的半个单位那么从这一位往左数到第一位非零数字一共几位就是几位有效数字。0.231与0.229的误差是0.002而0.231的百分位是3其半个单位是0.005。0.002小于0.005所以百分位是可靠的十分位的2也是可靠的但千分位的1已经不可靠。因此有效数字是2位而不是3位。实际判断时可以借助误差限与小数位的关系误差不超过0.5×10⁻ⁿ则从小数点后第n位往左都是有效数字。def significant_digits(approx, exact): error abs(approx - exact) import math if error 0: return None # 找到误差限对应的小数位 n math.floor(math.log10(error)) # 误差的数量级 # 有效数字位数 从最高位非零数字到误差限所在位 # 这里简化直接用误差限判定 return f误差 {error:.3f} 0.5e{n}, 可靠位到小数点后第{-n}位 print(significant_digits(0.231, 0.229))这段代码的核心是计算误差的数量级从而判断误差限落在哪一位。实际手算时不需要这么复杂只需要把误差与各个数位的半个单位比较即可。这个知识点是后续相对误差、舍入误差分析的基础试卷后面几道填空都是它的延伸。2.2 相对误差与有效数字位数√20的近似值要取几位试卷第8题问要使√20的近似值相对误差小于0.1%至少要取几位有效数字。答案是4位。这里用到一个重要结论如果一个数有n位有效数字那么它的相对误差上限约为1/(2a₁)×10⁻⁽ⁿ⁻¹⁾其中a₁是最高位数字。√20约等于4.472最高位数字a₁4。如果取4位有效数字即4.472相对误差约为|4.4721359-4.472|/4.4721359≈0.00003远小于0.1%。如果只取3位有效数字即4.47相对误差约为0.00048也小于0.1%。按严格公式计算要求相对误差小于0.1%需要的有效数字位数n满足1/(2×4)×10⁻⁽ⁿ⁻¹⁾0.001解得n≥3.1因此至少取4位。这类题的本质是有效数字位数与相对误差上限之间的换算考试时直接套公式即可。2.3 四种误差的区分在判断题里反复出现第6题判断“从实际问题的精确解到实际的计算结果间的误差有模型误差、观测误差、截断误差及舍入误差”这个说法是对的。第9题判断“数值计算中的总误差如果只考虑截断误差和舍入误差则误差的最佳分配原则是截断误差舍入误差”这个也是对的。这两道题放在一起其实是在考察对误差来源的分类意识误差类型来源是否可控模型误差实际问题抽象为数学模型时忽略次要因素建模阶段控制观测误差测量数据不精确实验阶段控制截断误差用有限项近似无穷过程如泰勒展开截断增加项数可减小舍入误差计算机浮点数有限字长引起提高精度可减小判断题里容易错的点是第10题“插值计算中避免外插是为了减少舍入误差”答案是错的。避免外插是为了减少截断误差因为外插点远离插值区间时插值余项中的(x-x₀)(x-x₁)…会迅速增大。区分这两类误差的此消彼长关系是误差分析中最重要的思维之一。2.4 范数估计题不计算‖AX‖∞也能给上界第2题给A[[1,2],[2,3]]X(1,2)ᵀ要求‖A‖∞、‖X‖∞和‖AX‖∞的上界。答案是‖A‖∞5行范数取各行绝对值之和的最大值‖X‖∞3取向量分量绝对值的最大值‖AX‖∞≤‖A‖∞·‖X‖∞15。这道题考察的是范数的相容性条件不需要真的算出AX再取范数。行范数∞的计算方法是对矩阵每一行求绝对值之和取最大值。第一行|1||2|3第二行|2||3|5所以‖A‖∞5。向量∞范数就是最大绝对值分量‖X‖∞max(1,2)2这里需要注意题目给的X如果是(1,2)ᵀ那么‖X‖∞2不是3。但答案写的3说明试卷里的X可能是(1,2,3)ᵀ或类似形式。无论如何核心结论不变矩阵范数与向量范数满足相容性‖AX‖≤‖A‖·‖X‖这个不等式在误差分析中用来估计解的扰动上界。3. 插值法全流程差商表、Hermite插值与截断误差3.1 差商与牛顿插值为什么f[2⁰,…,2⁷]1而再加一项变成0第4题给f(x)x⁷−x³1求f[2⁰,2¹,…,2⁷]和f[2⁰,2¹,…,2⁸]。答案分别是1和0。这里的关键结论是n次多项式的n阶差商等于其最高次项系数高于n阶的差商等于0。f(x)是7次多项式所以7阶差商f[2⁰,…,2⁷]等于最高次项系数1而8阶差商f[2⁰,…,2⁸]等于0。这个性质在构造牛顿插值多项式时非常有用——只要看到被插函数是多项式就能直接写出最高阶差商不需要真的去列差商表。import numpy as np def divided_difference(x_nodes, y_nodes): 计算牛顿差商表 n len(x_nodes) table np.zeros((n, n)) table[:, 0] y_nodes for j in range(1, n): for i in range(n - j): table[i, j] (table[i1, j-1] - table[i, j-1]) / (x_nodes[ij] - x_nodes[i]) return table # 验证f(x)x^7-x^31插值节点取2^0~2^7 x_nodes [2**i for i in range(8)] y_nodes [x**7 - x**3 1 for x in x_nodes] table divided_difference(np.array(x_nodes, dtypefloat), np.array(y_nodes, dtypefloat)) print(f7阶差商: {table[0, 7]:.6f}) # 应该接近1 print(f8阶差商: {table[0, 8]:.6f} if len(x_nodes) 8 else 需要更多节点)这段代码构建了完整的牛顿差商表table[i,j]表示以x_i到x_{ij}为节点的j阶差商。运行后可以看到7阶差商精确等于1这就是多项式最高次项的系数。实际应用中如果差商表中某一阶开始出现接近0的值说明当前多项式阶数已经足够拟合数据。3.2 Hermite插值带导数条件的差商表怎么列第2道计算题要求用牛顿-埃尔米特插值法求满足条件的四次插值多项式P₄(x)。已知x₀0时f1且f1x₁1时f-1且f5x₂2时f3。答案给出的P₄(x)1-2x-3x(x-1)-x(x-1)²(x-2)。构造Hermite插值的标准方法是把带导数的节点重复出现然后列扩展的差商表。具体来说x0出现两次x1出现两次x2出现一次总共5个条件对应4次多项式。重复节点处的差商f[x₀,x₀]就是f(x₀)f[x₀,x₀,x₁]用导数差商计算。试卷答案里的差商表是逐步算出来的核心步骤是x_if(x_i)一阶差商二阶差商三阶差商四阶差商01-2-34-101-2321-14-11-1123从表中读取系数牛顿形式的插值多项式为P₄(x)1-2x-3x(x-1)4x(x-1)²-x(x-1)²(x-1)这里需要仔细比对试卷答案。试卷给的P₄(x)1-2x-3x(x-1)-x(x-1)²(x-2)化简后是-x⁴7x³-14x²6x1。截断误差表达式为R₄(x)f⁽⁵⁾(ξ)/5!·x(x-1)²(x-2)²。注意因为节点x0和x1各重复一次余项中对应因子要平方。3.3 前插公式、后插公式与拉格朗日基函数的取舍第6题填空等距节点下节点靠近首节点用牛顿前插公式靠近尾节点用后插公式。如果要估计舍入误差选用拉格朗日插值公式。这题的前半部分考的是差分公式的适用场景后半部分考的则是拉格朗日基函数的一个重要性质。第7题说拉格朗日插值公式中系数aᵢ(x)的特点是Σaᵢ(x)1当aᵢ(x)满足什么条件时计算不会放大f(xᵢ)的误差。答案是aᵢ(x)1不对应该是aᵢ(x)之和为1且各aᵢ(x)非负时误差不会被放大。试卷答案写的是aᵢ(x)1但这显然有误——正确的条件是所有基函数非负这样Σ|aᵢ(x)|Σaᵢ(x)1误差传递系数为1不会放大。这个细节也提醒我们做真题时答案也可能有笔误需要自己验证原理是否正确。3.4 样条插值的连续性与分段插值的判断题第5题填空问三次样条插值函数S(x)在[a,b]上具有直到几阶的连续导数答案是2阶。三次样条在每个子区间上是三次多项式连接点处要求函数值、一阶导数和二阶导数都连续所以总体具有C²连续性。第4题判断“样条插值是一种分段插值”答案是√。这两题放在一起是为了区分样条插值和普通多项式插值普通多项式插值在整个区间上用同一个多项式样条插值分段用低次多项式但保证连接处光滑。一个常见误区是认为样条插值就是简单地分段做三次多项式插值。实际不是分段三次多项式插值只保证函数值连续而样条还强制了一阶导数和二阶导数连续因此需要额外求解三对角方程组来确定各段的系数。这也是为什么实际工程中样条比高阶多项式插值更稳定——Runge现象在高次插值中会让端点附近误差急剧放大样条通过限制次数和强制光滑来解决这个问题。4. 线性方程组求解列主元消元与迭代法的收敛条件4.1 列主元高斯消元的完整手算过程第1道计算题要求用列主元高斯消元法解方程组并且小数点后保留5位。试卷的解答过程写得非常详细是复习直接法的最好素材。方程组为x₁ - x₂ 2x₃ 1 5x₁ 4x₂ - 3x₃ 2 2x₁ - x₂ 3x₃ 1第一步检查第一列系数的绝对值|1|、|5|、|2|最大的是5位于第二行交换第1行和第2行。交换后系数矩阵变为[[5,4,-3],[1,-1,2],[2,-1,3]]。第二步计算消元系数l₂₁1/50.2l₃₁2/50.4。对第二行执行第二行减去0.2倍的第一行得到[0,-1.8,2.6]对第三行执行第三行减去0.4倍的第一行得到[0,-2.6,4.2]。第二步消元前先看第二列从第2行开始的元素|-1.8|和|-2.6|最大的是-2.6位于第三行交换第2行和第3行。然后计算l₃₂-1.8/(-2.6)0.69231。消元后回代得到x₃1.00010x₂1.99999x₁3.00005。import numpy as np def partial_pivot_gauss(A, b): 列主元高斯消元法求解 Axb n len(b) A A.astype(float).copy() b b.astype(float).copy() for col in range(n): # 选主元找当前列绝对值最大的行 pivot_row np.argmax(np.abs(A[col:, col])) col if pivot_row ! col: A[[col, pivot_row]] A[[pivot_row, col]] b[[col, pivot_row]] b[[pivot_row, col]] # 消元 for row in range(col 1, n): factor A[row, col] / A[col, col] A[row, col:] - factor * A[col, col:] b[row] - factor * b[col] # 回代 x np.zeros(n) for i in range(n - 1, -1, -1): x[i] (b[i] - A[i, i1:] x[i1:]) / A[i, i] return x A np.array([[1, -1, 2], [5, 4, -3], [2, -1, 3]]) b np.array([1, 2, 1]) x partial_pivot_gauss(A, b) print(f解向量: {x})列主元消元的意义在于避免小主元导致的误差放大。如果第一行第一列元素接近0直接消元会产生巨大的乘数把舍入误差放大。选择绝对值最大的元素作为主元可以保证消元系数|factor|≤1从而控制误差传播。这是高斯消元法与朴素高斯消元法最本质的区别也是考试中为什么要求保留5位小数的原因——列主元能保证在这个精度下得到稳定的结果。4.2 严格对角占优与Jacobi、Gauss-Seidel迭代第3道计算题要求对线性方程组做等价变换使Jacobi迭代和Gauss-Seidel迭代都收敛。原始方程组为4x₁ - x₂ 3x₃ 6 x₁ 4x₂ - x₃ 3 x₁ 2x₂ 3x₃ 8 x₁ - 3x₂ 4x₃ 5试卷的答案是交换第二个和第四个方程使系数矩阵变成严格对角占优。交换后4x₁ - x₂ 3x₃ 6 x₁ - 3x₂ 4x₃ 5 x₁ 4x₂ - x₃ 3严格对角占优的条件是每个对角元绝对值大于该行其他元素绝对值之和第1行|4||-1||3|4严格大于才算占优这里|4不够严格。所以试卷答案可能还需要进一步调整。这里的关键结论是如果系数矩阵严格对角占优则Jacobi迭代和Gauss-Seidel迭代都收敛。这是一个充分条件不是必要条件。迭代法收敛的充分条件收敛速度Jacobi严格对角占优或谱半径ρ(B_J)1较慢Gauss-Seidel严格对角占优或ρ(B_GS)1通常快于Jacobi但不绝对实际应用中判断ρ(B)1才是最根本的收敛条件。第9题填空“迭代公式x⁽ᵏ⁺¹⁾Bx⁽ᵏ⁾g收敛于精确解x*的充分必要条件是ρ(B)1”考察的就是谱半径条件。严格对角占优只是ρ(B)1的一个易于验证的充分条件。如果一个方程组不满足对角占优可以通过交换方程顺序、重新组合方程等方式调整系数矩阵的结构这正是第3道计算题的考察目的。4.3 松弛迭代法的残差公式与SOR方法第12题填空考察松弛迭代法中的残差定义rᵢ(bᵢ-aᵢ₁x₁-aᵢ₂x₂-⋯-aᵢₙxₙ)/aᵢᵢ。这个残差其实就是每个方程在当前迭代值下的不平衡量除以对角元。松弛迭代SOR的思想是在Gauss-Seidel的基础上引入松弛因子ω通过逐步减小残差来加速收敛。SOR的迭代格式为xᵢ⁽ᵏ⁺¹⁾xᵢ⁽ᵏ⁾ω·rᵢ⁽ᵏ⁾其中ω是松弛因子。ω1时退化为Gauss-Seidelω1是超松弛ω2是赛德尔迭代。值得注意的是SOR要求0ω2才能保证收敛。这种方法在实际工程中非常常用因为当系数矩阵是大型稀疏矩阵时直接法会破坏稀疏性迭代法是更好的选择。4.4 平方根法与严格对角占优的判断题陷阱判断题第3题说“若A为n阶方阵且满足严格对角占优条件则高斯-塞德尔迭代法一定收敛”答案是√这是严格对角占优的保证。但第7题说“平方根直接解法适用于任何线性方程组AXb”答案是×因为平方根法Cholesky分解只适用于对称正定矩阵。第1题说“若A非奇异则一定可以使用高斯消元法”答案是×因为非奇异只能保证解存在唯一如果主元为0且无法通过换行解决消元过程会失败。这两组判断题放在一起考察的是对方法适用条件的精确记忆。每种数值方法都有自己的前提条件高斯消元要求每一步主元非零列主元可以放宽这个限制Cholesky要求对称正定Jacobi和Gauss-Seidel要求谱半径小于1。很多工程问题中错误选择了不适用条件的解法会导致计算发散或精度崩溃这些判断题就是在训练这种条件的敏感性。5. 非线性方程求根从牛顿迭代法到收敛性判断5.1 迭代收敛条件与牛顿下山法第3题填空要求写出迭代函数xφ(x)局部收敛的条件答案是|φ(x)|1。这是迭代法的基本收敛定理在不动点x*附近如果φ(x)的绝对值小于1则迭代局部收敛。第11题考察牛顿下山法的下山条件|f(xₙ₊₁)||f(xₙ)|即每次迭代后函数绝对值必须减小否则需要调整下山因子λ。牛顿下山法是对牛顿法的改进。标准牛顿法在初值不理想时可能发散下山法引入因子λ迭代格式变为xₙ₊₁xₙ-λ·f(xₙ)/f(xₙ)每一步检查是否满足下山条件不满足就缩小λ直到满足。这种做法在实际工程中被广泛用于提高牛顿法的全局收敛性代价是牺牲了一点收敛速度。判断第2题“牛顿法在单根附近是平方收敛的”答案是√这也是牛顿法最重要的理论优势。5.2 初始点的选取依据f(x₀)f(x₀)0第13题考察切线法迭代中初始点x₀的选取依据。当f(x)在迭代区间存在唯一解且f(x)不变号时初始点需要满足f(x₀)·f(x₀)0。这个条件的几何意义是初始点处的函数值方向与曲率方向一致确保切线迭代不会越过极值点产生振荡。其实质是保证牛顿法的迭代序列单调收敛。理解这个条件最好的方式是从几何上看。牛顿法的迭代公式xₙ₊₁xₙ-f(xₙ)/f(xₙ)在几何上是过点(xₙ,f(xₙ))作切线与x轴的交点作为下一个近似。如果f(x)0函数下凸那么需要f(x₀)0才能保证切线与x轴的交点在根的右侧从而单调递减逼近根。选错初值时迭代可能先远离根再进行一轮无效的计算浪费算力甚至发散。5.3 拉格朗日插值取小数位数的反问题第4道计算题是个很有意思的反问题设ysinx已知x₀1.74、x₁1.76、x₂1.78时用拉格朗日插值计算x1.75的函数值问y₀、y₁、y₂应取几位小数。这类问题的解题思路是利用插值余项和舍入误差的平衡。需要保证函数值的舍入误差经过拉格朗日基函数加权后不超过插值余项的截断误差。sinx在[1.74,1.78]区间内的三阶导数绝对值的最大值是|cosx|≤1所以截断误差约为|f(ξ)/3!·(x-x₀)(x-x₁)(x-x₂)| ≤ 1/6 × |(0.01)(-0.01)(-0.03)| ≈ 5×10⁻⁷。因此函数值如果取5位小数舍入误差为0.5×10⁻⁵5×10⁻⁶加权后仍在可接受范围内。这道题的本质是误差平衡思想输出精度由截断误差和舍入误差共同决定两者需要匹配取太少小数位会让舍入误差盖过截断误差取太多则浪费计算量。5.4 牛顿法求√a的迭代公式与Python验证第6道计算题要求应用牛顿法于方程f(x)x²-a0导出求√a的迭代公式并用此公式求√115的值。牛顿迭代公式为xₙ₊₁ xₙ - f(xₙ)/f(xₙ) xₙ - (xₙ²-a)/(2xₙ) (xₙ a/xₙ)/2这个公式在数值分析中极其重要因为它就是计算机中实现开方运算的基本算法之一。初始值可以取x₀a/2或x₀1然后迭代几次就能收敛到很高精度。试卷要求求√115并保留4位小数从x₀10开始迭代def newton_sqrt(a, x0, tol1e-6, max_iter100): 牛顿法求平方根: x_{n1} (x_n a/x_n) / 2 x x0 history [] for i in range(max_iter): x_next 0.5 * (x a / x) # 迭代公式 history.append(x_next) if abs(x_next - x) tol: # 收敛判据两次迭代差足够小 print(f迭代 {i1} 次收敛) break x x_next return x, history result, history newton_sqrt(115, 10) print(f√115 ≈ {result:.6f}) print(f迭代过程: {[f{h:.6f} for h in history]}) # 与numpy结果对比 print(fnumpy结果: {np.sqrt(115):.6f})这段代码展示的是牛顿法求平方根的完整实现。迭代公式的核心是x_next 0.5 * (x a / x)这条语句同时完成了求平均和修正两项工作x与a/x的平均值总是比x更接近√a无论初始值偏大还是偏小序列都会快速收敛。收敛判据用两次迭代的差值小于容差这是工程中最实用的停机准则。一般情况下x₀取10第2次迭代就能达到10⁻⁶量级的精度第3次迭代已经到10⁻¹²量级这正是平方收敛的典型速度——有效数字翻倍增长。这种收敛速度让牛顿法成为迭代法中最亮眼的方法之一代价是每步需要计算导数在导数计算昂贵时可以考虑割线法替代。本文还有配套的精品资源点击获取