简介:《科学与工程计算》(熊春光版)期末复习笔记,是一份面向北京理工大学自动化等专业学生的课程重点梳理,适合考前系统回顾和平时查漏补缺。笔记围绕微分方程数值解法展开,详细整理了初值问题与边值条件、二阶常微分方程的定解要求,并重点推导了有限差分法、中心差商近似、内部截断误差及矩阵方程构造过程;对Lagrange插值、三次样条插值与配置法、B样条基函数等内容也做了条理化总结,可帮助读者理解Runge现象、样条连续性与数值解的构造逻辑。资源包为单文件PDF,共20.04MB,内容集中、可直接检索阅读,已有2754人学习下载。笔记以教材章节为主线,归纳了各类数值方法的适用条件和求解步骤,便于快速定位复习重点,对自动化专业学生掌握控制系统数学建模与工程计算很有帮助。
1. 期末复习笔记,先搞清楚这门课到底在考什么
期末最怕的不是题难,而是翻书发现每章都熟、合上书发现哪道题都下不了手。《科学与工程计算》熊春光版就是这样一门课:名字听着像“用计算机算数学”,实际考的是三件事——你会不会把连续问题离散化、会不会估误差、能不能把算法写成能跑出数的步骤。很多A同学抱着“背公式就能过”的心态进考场,结果栽在插值节点写错、迭代判据选错、复化积分区间数错这类问题上。
这门课的复习笔记,核心价值不在此刻抄一遍笔记,而在于考前把“考点分布—公式体系—代码实现—手算套路”串成一条可验证的链路。这篇文章我按期末冲刺的顺序来写:先看考点地图,再给可直接跑的代码,最后集中排掉高频丢分点。适合两类人:一是平时听课但对“怎么考”没概念的,二是已经刷过题但总在固定题型上翻车的。读的时候建议开一个 Python 环境,遇到代码就跟着敲一遍,十五分钟见效。
2. 考点地图与公式体系:8 类必考算法的选型逻辑
2.1 插值与拟合:拉格朗日、牛顿差分、最小二乘的取舍
插值类题目考的是“给一组离散点,求某个非节点位置的值”。拉格朗日插值写法直观,适合节点数少(3 到 5 个点)的手算题;牛顿插值借助差商表,新增节点时不用重算全部基函数,程序实现上比拉格朗日更有优势。最小二乘拟合则完全是另一种思路:数据带误差时用插值会画出剧烈抖动的曲线,拟合反而能逼近整体趋势。
选型逻辑我一般这样记:节点数小于等于 4、题目明确要求“求近似值”,优先拉格朗日;节点多且逐步加密,用牛顿差商表;出现“测量数据”“观测值”“使误差平方和最小”这类关键词,直接转最小二乘。误差角度上,插值余项为 f 的 n+1 阶导数除以 (n+1)! 再乘零点多项式,这类题常配合“估计误差上界”出现,需要先求高阶导数,再找区间内绝对值的最大值。
手算时容易漏的是差商表的分数线写法。一阶差商 f[x0,x1]=(f1-f0)/(x1-x0),二阶差商 f[x0,x1,x2]=(f[x1,x2]-f[x0,x1])/(x2-x0),层层往右下角推,最后用牛顿插值公式 P(x)=f[x0]+f x0,x1 +f x0,x1,x2 (x-x1)+…。注意每一项多乘一个因式,次数跟着往上加。
2.2 数值积分与微分:梯形、Simpson 复化与误差阶
积分题的核心是“用有限个点把曲线下的面积凑出来”。复化梯形公式把区间分成 n 份,每份用梯形近似,精度是 O(h²);复化 Simpson 公式每两个小区间合成一段,用抛物线近似,精度是 O(h⁴)。同样节点数下,Simpson 的精度通常比梯形高一到两个数量级,这是期末最常考的选型判断。
误差项必须背到“能写对系数”的程度。梯形公式的截断误差是 -(b-a)/12·h²·f″(η),Simpson 公式是 -(b-a)/180·h⁴·f⁽⁴⁾(η),η 都在区间内。实际计算时最常见的问题是:复化梯形公式和复化 Simpson 公式所需的节点数不一致。梯形有 n+1 个节点,Simpson 则要求区间数 m 为偶数,节点数是 2m+1,算 h 时用的是区间长度除以 m 而不是除以节点数。
还有一个高频技巧是变步长积分:先算 T₁,再把步长减半算 T₂,用 |T₂-T₁| < ε 判断是否继续加密。这个方法期末题里常以“取几次二分达到指定精度”的形式出现,每次二分只需计算新增的中间点,不要重新算整段。
2.3 线性方程组与非线性求根:直接法与迭代法的收敛条件
线性方程组部分考两条线。直接法以高斯消元、LU 分解、追赶法为代表,适合中小规模稠密矩阵;迭代法以 Jacobi 和 Gauss-Seidel 为代表,适合稀疏矩阵,但必须先判断收敛性。考试里最常见的坑是拿 Jacobi 迭代硬算一个不满足收敛条件的矩阵,算到第十步还在振荡,白白浪费时间。
判断收敛有三种层次:严格对角占优一定收敛;谱半径小于 1 是充要条件,但求谱半径考试时计算量大;对称正定矩阵用 Gauss-Seidel 必收敛。做题时先看对角占优,再看题目是否给出“迭代矩阵范数小于 1”,都不满足就老实判断谱半径。迭代法写答案时要把迭代格式写完整,x[k+1] 的每个分量都要展开写,不要只写矩阵形式。
非线性求根部分,二分法稳定但慢,牛顿法快但要求导数不为零且初值靠近根。期末计算套路是:先用二分法或画图找区间 [a,b],再用牛顿法加速(我一般会把二分法先迭代两轮,把初值送到根的邻域里,再切牛顿法,能减少发散概率)。不动点迭代则要额外判断 |φ′(x)|<1 的压缩条件,否则序列不收敛。
2.4 常微分方程数值解:显式欧拉、改进欧拉、RK4 的稳定性
常微分方程初值问题在期末试卷上通常占最后一道大题,考法很固定:给一个 y′=f(x,y) 和初始条件,要求用指定方法算到某一点的近似值。显式欧拉公式 y_{n+1}=y_n+h·f(x_n,y_n) 是最基础的;改进欧拉(也叫预报-校正法)先算预测值,再用预测值算校正值,精度为 O(h²);四阶经典 Runge-Kutta 方法精度为 O(h⁴),是手算题的上限,节点多时计算量非常大。
稳定性是另一个考点。显式欧拉对步长敏感,步长太大时数值解会振荡甚至发散,尤其出现在刚性方程里;隐式欧拉稳定但计算量大,期末一般只要求知道“隐式比显式稳定”这个结论。实际做题时先用题目指定方法,如果题目同时让“比较不同步长的结果”,就按误差阶去预判:步长减半,欧拉误差约减为一半,RK4 误差约减为 1/16。这个预判能用来核对计算结果有没有算飞。
3. 重点算法按代码复现:期末能直接照抄的 Python 实现
3.1 插值模块:拉格朗日与最小二乘的完整实现
复习笔记里代码部分的价值在于:手算只能验证 3 到 5 个节点的小题,代码可以让你在考前快速验证公式有没有记错。拉格朗日插值写起来很短,但最容易错的是基函数的分母和循环边界。
def lagrange_interp(x_nodes, y_nodes, x): """ 拉格朗日插值:给定节点数组与查询点 x,返回插值结果 x_nodes: 已知节点的 x 坐标列表 y_nodes: 已知节点的 y 坐标列表,长度需与 x_nodes 一致 x: 待求近似的点(可以是单个数值) """ total = 0.0 n = len(x_nodes) for i in range(n): # 计算第 i 个基函数 L_i(x) li = 1.0 for j in range(n): if j != i: li *= (x - x_nodes[j]) / (x_nodes[i] - x_nodes[j]) total += y_nodes[i] * li return total # 示例:节点 (0,1), (1,3), (2,2),求 x=0.5 的近似值 xs = [0, 1, 2] ys = [1, 3, 2] print(lagrange_interp(xs, ys, 0.5)) # 输出 2.5逻辑说明:外层循环遍历每个节点,内层循环累乘构造基函数,x_nodes[i] - x_nodes[j] 是基函数分母。分母为零的情况只会出现在 i=j,已经被 if 跳过。参数上要注意 x_nodes 和 y_nodes 必须同长度,且查询点 x 不要和某个节点完全相等,否则会触发除以接近零的数,虽然结果不出错,但会被浮点数误差干扰。
最小二乘拟合我通常会带着法方程一起写,因为期末考“求拟合多项式”时,手算步骤就是解法方程。下面的代码演示一次多项式拟合 y = a + bx。
import numpy as np def linear_least_squares(x_data, y_data): """ 一次多项式最小二乘拟合:返回系数 [a, b],即 y = a + b*x x_data, y_data: 观测点数组 """ n = len(x_data) s_x = sum(x_data) s_y = sum(y_data) s_xx = sum(x**2 for x in x_data) s_xy = sum(x_data[i] * y_data[i] for i in range(n)) # 法方程: [n s_x] [a] = [s_y] # [s_x s_xx][b] [s_xy] det = n * s_xx - s_x * s_x a = (s_xx * s_y - s_x * s_xy) / det b = (n * s_xy - s_x * s_y) / det return a, b # 示例数据 x_obs = [0, 1, 2, 3] y_obs = [1.1, 2.9, 4.2, 6.1] print(linear_least_squares(x_obs, y_obs)) # 约 (0.95, 1.66)这里法方程的行列式 det 如果接近零,说明数据点几乎共线且 x 没有变化,拟合本身没有意义。对期末复习来说,这段代码最大的作用是验证手算结果:先手算法方程,再用代码跑一遍,两边对不上就从累加项里找漏项。
3.2 线性方程组:LU 分解与 Jacobi 迭代的代码与收敛判据
线性方程组的代码实现,我建议复习时重点看两段:一段是列主元 LU 分解,一段是 Jacobi 迭代。前者对应直接法考试题型,后者对应迭代法判敛题型。
import numpy as np def lu_decompose(A): """ 列主元 LU 分解:返回 P, L, U,满足 P@A = L@U A: numpy 二维数组,方阵 """ n = A.shape[0] A = A.copy().astype(float) L = np.eye(n) U = np.zeros_like(A) P = np.eye(n) for k in range(n): # 选取 k 列中绝对值最大的元素作为主元 pivot = np.argmax(np.abs(A[k:, k])) + k if pivot != k: A[[k, pivot], :] = A[[pivot, k], :] P[[k, pivot], :] = P[[pivot, k], :] # 前面列已经处理过的 L 也要交换 L[[k, pivot], :k] = L[[pivot, k], :k] L[k, k] = 1.0 for i in range(k+1, n): L[i, k] = A[i, k] / A[k, k] A[i, k:] -= L[i, k] * A[k, k:] U[k, k:] = A[k, k:] return P, L, U # 测试:3x3 矩阵 A = np.array([[2, 1, 1], [4, 1, 0], [-2, 2, 1]], dtype=float) P, L, U = lu_decompose(A) print("L:\n", L, "\nU:\n", U, "\nP@A == L@U ?") print(np.allclose(P @ A, L @ U))参数说明:主元选择是用 argmax 找当前列绝对值最大的行;交换行时 L 矩阵左边已经填好的部分也要跟着交换,这是初写代码最容易漏的一步。做期末手算题时,列主元的意思是每一步消元前先比较 |a_kk| 和下方各元素绝对值,把最大者所在行换到对角线位置,若主元为零直接换行。
Jacobi 迭代代码则要展示“迭代矩阵”和“停机判据”两个关键点。期末计算时不需要真的构造迭代矩阵,直接用分量更新公式即可。
def jacobi_iterate(A, b, x0, tol=1e-6, max_iter=100): """ Jacobi 迭代求解 Ax=b A: 系数矩阵(严格对角占优时效果最好) b: 右端向量 x0: 初始猜测向量 tol: 相邻两次迭代解的无穷范数相对误差阈值 """ n = A.shape[0] x = np.array(x0, dtype=float) for k in range(max_iter): x_new = np.zeros_like(x) for i in range(n): sigma = 0.0 for j in range(n): if j != i: sigma += A[i, j] * x[j] x_new[i] = (b[i] - sigma) / A[i, i] # 收敛判据:||x_new - x||_inf / ||x_new||_inf < tol err = np.max(np.abs(x_new - x)) / (np.max(np.abs(x_new)) + 1e-12) x = x_new if err < tol: print(f"迭代 {k+1} 次收敛") return x print("达到最大迭代次数,未收敛") return x A = np.array([[10, -1, 2], [-1, 11, -1], [2, -1, 10]], dtype=float) b = np.array([6, 25, -11], dtype=float) print(jacobi_iterate(A, b, [0, 0, 0]))这段代码的收敛判据用的是相对误差,分母加 1e-12 是为了防零。考试时如果题目只给“误差不超过 1e-3”,默认用相对误差还是绝对误差要以教材为准,我复习时会把两种判据都写在笔记旁边,看到题目写“绝对误差”就换成分母为 1 的形式。
3.3 常微分方程:欧拉法与 RK4 的逐行拆解
常微分方程部分的代码复习价值最高,因为手算 RK4 时四个斜率 k1 到 k4 的先后顺序非常容易错,代码可以当“参考答案”用。
def euler_explicit(f, x0, y0, h, n): """ 显式欧拉法求解 y'=f(x,y), y(x0)=y0 f: 右侧函数,接受 (x, y) 返回导数值 h: 步长 n: 迭代步数 """ xs = [x0] ys = [y0] x = x0 y = y0 for _ in range(n): y = y + h * f(x, y) x = x + h xs.append(x) ys.append(y) return xs, ys # 示例:y' = y, 精确解 e^x,取 h=0.1 计算前 10 步 import math f = lambda x, y: y xs, ys = euler_explicit(f, 0.0, 1.0, 0.1, 10) print(ys[-1], math.exp(1.0)) # 数值解约 2.5937,精确解约 2.7183显式欧拉的逻辑是:用当前点的斜率推下一点,步长 h 越小精度越高但舍入误差累积也会增加。期末题目通常只要求算两三步,手算时注意每一步的 x 和 y 都要更新,不要出现“用旧 y 配新 x”这种错位。
RK4 的代码则要严格体现“四个斜率取加权平均”的结构。
def rk4(f, x0, y0, h, n): """ 四阶经典 Runge-Kutta 方法求解 y'=f(x,y) 每一步计算 k1,k2,k3,k4,再做加权平均 """ xs = [x0] ys = [y0] x = x0 y = y0 for _ in range(n): k1 = f(x, y) k2 = f(x + h/2, y + h/2 * k1) k3 = f(x + h/2, y + h/2 * k2) k4 = f(x + h, y + h * k3) y = y + h/6 * (k1 + 2*k2 + 2*k3 + k4) x = x + h xs.append(x) ys.append(y) return xs, ys # 同一例题,RK4 在 h=0.1 时的精度远高于欧拉 xs, ys = rk4(f, 0.0, 1.0, 0.1, 10) print(ys[-1], math.exp(1.0)) # 约 2.71827参数与顺序说明:k2 与 k3 都取中点斜率,区别在于 k2 用 k1 预报中点值,k3 用 k2 预报中点值;k4 用 k3 预报终点值。加权系数是 1/6、2/6、2/6、1/6,手算时容易把 2 倍系数漏掉,代码跑完对照手算中间量就能立刻发现哪里少乘了 2。
3.4 变步长积分与追赶法:两个高频但容易被跳过的小算法
变步长梯形积分是期末“至少二分多少次达到精度”题目的标准解法。先放代码,再讲判据。
def trapezoid_adaptive(f, a, b, tol=1e-4, max_depth=20): """ 逐次分半的复化梯形积分:自动加密步长直到误差估计满足 tol f: 被积函数 a,b: 积分区间 tol: 前后两次积分结果的差值阈值 """ n = 1 h = b - a T_old = h * (f(a) + f(b)) / 2.0 for depth in range(1, max_depth + 1): # 只在新增的中间点计算 f 值 sum_mid = 0.0 for k in range(1, 2**(depth-1) + 1): x_mid = a + (2*k - 1) * h / (2**(depth)) sum_mid += f(x_mid) T_new = T_old / 2.0 + (h / (2**depth)) * sum_mid if abs(T_new - T_old) < tol: return T_new, depth T_old = T_new return T_old, max_depth import math res, depth = trapezoid_adaptive(lambda x: math.sin(x), 0, math.pi, tol=1e-5) print(res, depth) # 接近 2.0逻辑说明:T_new = T_old / 2 + (h/2^depth)·Σf(新增中点),这个递推式把上次结果折半,再补上新算的中间点。参数上 tol 控制精度,max_depth 防止无限循环;期末手算时不用真的写循环,按“T1 → T2 → T4 → …”算到差值小于阈值即可。注意题目如果要求“绝对误差”,要用 |T_new - T_old| 判断;如果要求“直到误差小于 ε”,很多教材直接以两次结果之差近似误差项,按课本约定写就行。
追赶法解三对角方程组在数值微分和三次样条里都会用到,手算和代码都要熟练。核心思路是先消去下对角线,再回代。
def thomas_solve(a_diag, b_diag, c_diag, d_vec): """ 追赶法解三对角方程组 a_diag, b_diag, c_diag 分别对应下对角线、主对角线、上对角线 d_vec 为右端向量 """ n = len(b_diag) cp = [0.0] * n dp = [0.0] * n # 追:向前消元 cp[0] = c_diag[0] / b_diag[0] dp[0] = d_vec[0] / b_diag[0] for i in range(1, n-1): m = b_diag[i] - a_diag[i] * cp[i-1] cp[i] = c_diag[i] / m dp[i] = (d_vec[i] - a_diag[i] * dp[i-1]) / m m = b_diag[n-1] - a_diag[n-1] * cp[n-2] dp[n-1] = (d_vec[n-1] - a_diag[n-1] * dp[n-2]) / m # 赶:回代求解 x = [0.0] * n x[n-1] = dp[n-1] for i in range(n-2, -1, -1): x[i] = dp[i] - cp[i] * x[i+1] return x # 示例:主对角线全为 4,两侧为 -1 a_diag = [-1, -1, -1, -1] b_diag = [4, 4, 4, 4] c_diag = [-1, -1, -1, -1] d_vec = [1, 2, 3, 4] print(thomas_solve(a_diag, b_diag, c_diag, d_vec))复习追赶法时注意:边界条件不同,首行和末行的公式会略有变化,三弯矩方程组里首末两行通常来自边界条件而不是微分方程,期末题很容易在“给自由端边界还是固支边界”上设坑。
4. 期末考题的三种计算套路:手算步骤与答案核对
4.1 表格类题型:差商表、逐次分半积分的规范写法
期末阅卷最看重“过程完整”。差商表题规范写法分四步:先列节点表,再逐列计算差商,然后用牛顿插值公式写出多项式,最后代入求值点。每一步保留至少 4 位有效数字,因为后续计算会持续放大舍入误差,中间值只留 2 位会导致最后一位完全失真,这是血泪教训。
逐次分半积分题规范写法是:T₁ → T₂ → T₄ → …… 每一步写清楚 h 和新增节点。比如 h 从 1 变 0.5,新增的中间点是 x=0.5;再变 0.25,新增的是 x=0.25 和 x=0.75。只算新增点的函数值,不要重复算旧点。最后一步写“|T_{2n} - T_n| = 具体数值 < ε”,用差值小于阈值为收尾判据。
4.2 迭代类题型:不动点迭代与牛顿法的收尾判据
迭代类题最容易被扣分的地方是“收尾判据不清”。题目说“误差不超过 1e-3”,答案要写“|x_{k+1} - x_k| ≤ 1e-3 时停止,取 x_{k+1} 为近似解”。如果不写这一句,只给最后一轮的计算结果,会被认为逻辑不完整。我复习时习惯把三种判据列在同一页:绝对误差 |x_{k+1}-x_k|、相对误差 |x_{k+1}-x_k|/|x_{k+1}|、残差 |f(x_k)|。题目给哪个词就选哪个,不要默认用残差。
牛顿法的规范步骤是:求导 f′(x) → 选初值 x₀ → 迭代 x_{k+1}=x_k-f(x_k)/f′(x_k) → 用判据停机。手算时每一步都写清楚分母的 f′(x_k) 是怎么算出来的,不要把分子分母交叉。遇到 f′(x_k)=0 的情况要立刻说明“此法失效,改用弦截法或重选初值”。
4.3 误差分析题型:截断误差与舍入误差的分界点
误差分析题通常给一个公式,问“截断误差还是舍入误差占主导”。这题的关键是把截断误差写成步长 h 的幂次形式,把舍入误差写成与机器精度 ε 相关。比如复化梯形公式,截断误差是 O(h²),h 越小误差越小;但 h 小到一定程度后,浮点舍入误差开始累积,总误差会先降后升。期末很少要求算极值点,但要求你能画出一条“先下降后上升”的误差曲线,并解释转折点来自舍入误差。
做题时先看题目给没给 f 的高阶导数表达式。给了就写出误差限的绝对值计算;没给就说明“截断误差项含 f″(η),需要估计 |f″(η)| 的上界”。不要编数值,宁可写成“M=1e-2”,也要注明 M 来自哪个导数范围。
4.4 常微分方程题型:步长选择与多步计算的答题模板
常微分方程手算题最容易因为“只写公式不写中间量”而丢分。以 RK4 为例,建议每一步单独占一块版面:先列 x₀、y₀、h,再依次列 k₁、k₂、k₃、k₄ 的计算过程,最后写出 y₁ 的加权求和式。即使算出结果和参考答案差一点,阅卷也能看到你卡在哪一步。
步长选择的预判很有用:题目最常给“分别用 h 和 h/2 计算,比较结果”。我一般会预先估计:显式欧拉步长减半,末端误差约减半;RK4 步长减半,末端误差理论减为 1/16。如果算出来减幅明显不对,说明某一步代入错了。最后检查一遍 x 方向的更新:每步结束 x 必须加 h;很多人算完 y 忘了更新 x,下一步的 k₁ 就全错。
5. 期末复习踩坑记录:5 个最容易丢分的隐蔽问题
5.1 现象:迭代收敛判断写错“相对误差”还是“绝对误差”
有同学在不动点迭代题里用 |x_{k+1} - x_k| 和 ε 比较,题目要求却是“相对误差不超过 1e-3”,答案最后一位完全对不上。原因是教材对“误差”一词在不同章节的默认含义不同:有的章节默认绝对误差,有的默认相对误差。
解决:考前把本课程的习惯用法统一写在一张便利贴上。做任何迭代题,落笔前先圈出题目里的“误差”修饰词——带“相对”就除以当前迭代值绝对值;什么都没写,就按教材例题的写法来,我在复习时会翻三道课后例题,确认教材默认用哪种。
5.2 现象:复化 Simpson 的节点数与区间数搞混,导致 h 算错
某次模拟卷里给出 n=8,有位同学直接代入 h=(b-a)/8,算出来和标准答案差出一倍。原因是题目说的 n 通常指“积分区间数”,Simpson 的节点数是 2n+1 而不是 n+1。
解决:拿到复化积分题先写两行公式——区间数 m、节点数 m+1(梯形)或 2m+1(Simpson),再代数字。h 一律等于 (b-a)/m,绝不等于 (b-a)/节点数。这个习惯能同时救梯形公式和 Simpson 公式两道题。
5.3 现象:牛顿法求导正确但初始值选错,直接发散
牛顿法在根附近收敛速度极快,但初值离根远时可能振荡甚至发散。最典型的翻车现场:题目给 f(x)=x³-x-1,同学选了 x₀=0,结果迭代序列在 0 和 -1 之间来回跳,算了六步还在振荡。
解决:先用二分法找含根区间,再取区间中点当牛顿法初值。考前我把这个习惯固定成流程:任何牛顿法题目先画草图或快速二分两三步,再进牛顿法。如果题目限定“必须用牛顿法且初值已给定”,那就按给定值算,但要在答案开头写明“初值可能不收敛,若序列振荡请改用二分法”的备注,至少能保住步骤分。
5.4 现象:追赶法解三对角方程组时边界条件漏项
追赶法公式里首行和末行的处理最特殊。首行没有 a₁ 项,末行没有 cₙ 项,直接套中间行的递推公式会让索引越界。更隐蔽的坑来自三次样条的边界条件:题目给“固支边界”,追赶法右端向量 d 的收尾项就多一列导数条件;给“自然边界”,端点二阶导为零,右端项也要相应改。
解决:考前把追赶法代码跑一遍三对角标准题,再手工跑一遍带自然边界的样条题,对比右端向量前后两个版本的区别。考试时先圈“边界条件”四个字,再决定 d 向量的头尾怎么填。
5.5 现象:RK4 的 k1/k2/k3/k4 顺序与步长更新不同步
手算 RK4 时间紧,最常见错误是算完 k₁ 后把 y 直接更新了,结果 k₂ 用的是新 y 而不是“y + h/2·k₁”。另一个错误是 h 更新和 y 更新顺序颠倒:先让 x 加了 h,再用旧 y 算下一步的 k₁,导致整体平移。
解决:把 RK4 的每一固定为五步——列当前 x、y;依次算 k₁ 到 k₄;只更新 y;最后才更新 x;进入下一步。代码里我习惯让 x 更新放在最后,手算时也照这个顺序写,能避开约 80% 的 RK4 手算错误。如果算到一半发现 y 和 x 对不上,第一时间检查是否在某一步提前加了 h。
5.6 现象:最小二乘的法方程列错,符号和求和项对不上
最小二乘拟合一次多项式时,法方程是 [n Σx; Σx Σx²]·[a;b]=[Σy;Σxy]。不少同学把第二个方程的 Σx 写成 Σx² 的一阶关系,或者把 Σxy 写成 Σy·Σx,后者在数据不均匀时误差极大。
解决:法方程不要背,而要从“残差平方和分别对 a、b 求导等于零”推导出来。考前花十分钟推一遍两个导数式,比背十遍式子都牢。考试时如果时间不够,就先把原始数据列成表格,逐列求和,再往法方程里填,能有效避免同行漏项。
6. 考前最后一个晚上的查漏方法:用“公式—题型—代码”倒推表
复习进入最后阶段,真正拉开差距的不是再多看一遍笔记,而是能不能在无提示状态下把每个算法从公式写到结果。我通常会用两个小时做一张倒推表:左边是算法名,中间是核心公式,右边是典型题型。比如“复化梯形”对应“给 f 和区间,求 n=4 的积分近似值与误差估计”,盖上笔记默写一遍,写不出来的就是薄弱点。
第二步是“代码对照”。笔记本里我准备了三个可复现脚本:插值与拟合、线性方程组迭代、RK4/欧拉。考前最后一晚不从头写,而是直接改参数跑一遍。改一个节点坐标、换一个矩阵元素、把步长从 0.2 改成 0.1,观察结果变化是否符合误差阶的理论预期。这一步能同时检验公式记忆和实际计算敏感度。
第三步是“限时手算”。找三道综合性真题,按考场时间只允许带计算器和草稿纸,全程不翻笔记。做完后对照笔记重点检查三处:迭代停机的判据用语、Simpson 的区间数 m 是否写对、RK4 中间量是否完整。这三处也是我每届带复习时学员出错率最高的位置,考前确认过一遍,基本就不会再丢。
我的个人习惯是把最后半天用在“默写公式卡片”而不是刷题。每张卡片正面写算法名,背面写核心公式、适用条件、典型坑各一行,比如“复化梯形:误差含 f″,不适用端点奇异的积分”。这个习惯源自早年一次期末,我把 Simpson 的误差阶记成 O(h²),结果某道 10 分大题结论全错,从那以后误差阶一律单独成卡。希望这份复习思路和代码能帮你在考场上少走几个弯路,拿到该拿的分。
本文还有配套的精品资源,点击获取