最近在 MoHub 上看到一套《数学试题Syslab 科学计算 48 题》从求导、积分一直做到优化和微分方程而且每道题都配了 Julia 脚本。我比较好奇的是这些题如果真的全部跑一遍结果能不能和数学答案对上于是我在 MWORKS Syslab 2026b 中把 48 个脚本逐个运行了一遍。整体结果不错47 题可以直接运行只有 1 题因为 Julia 作用域写法报错。更有意思的是实跑过程中还发现了几个只看参考答案不太容易注意到的问题。48 道题都在算什么题库分成四部分每部分 12 题模块主要内容高等数学极值、积分、极限、泰勒展开、傅里叶/拉普拉斯变换概率统计概率分布、置信区间、假设检验、回归、ANOVA、蒙特卡罗最优化线性/整数/非线性/凸优化、粒子群、遗传算法、模拟退火微分方程ODE、RK4、SIR、热传导、时滞方程、洛伦兹系统用到的主要是 TySymbolicMath、TyStatistics、TyOptimization、TyConvex、TyGlobalOptimization、DifferentialEquations 和 TyPlot。每道题都是一个独立的.jl文件所以不需要把整个项目搞明白选一道题就可以单独运行。高数部分符号结果和数值结果能对上前 12 题比较接近常见的大学高数实验。例如计算∫₀^π sin(x)dx符号积分得到2数值积分得到2.0000000000000004这里多出来的尾数只是浮点数表示造成的。多重积分也有类似现象∬(x²y²)dxdy区域为 [0,1]×[0,1]符号计算直接返回精确值2/3数值计算得到0.6666666666666669另外多项式求根、部分分式、拉普拉斯变换等结果也基本能和参考答案对应。不过泰勒展开这里遇到了一个小问题。题目希望得到sin(x)≈x−x³/6x⁵/120但脚本设置Order5后实际只返回x−x³/6我又调整参数试了几次发现这里的Order更接近“截断到哪个幂次”而不是“数学教材里所说的几阶展开”。设置到Order6之后x⁵/120 才会出现。图1 sin(x)的泰勒多项式逼近这不算算法错误但如果直接把“5 阶泰勒展开”和Order5画等号就容易产生理解偏差。概率统计结果每次不一样反而是正常的概率统计的 12 道题包括正态分布、二项分布、大数定律、置信区间、t 检验、回归、方差分析和蒙特卡罗等。其中有不少脚本使用随机数所以每次运行结果并不完全相同。例如大数定律实验本次运行得到n100.51209n1000.48662n10000.49906n100000.50684理论均值是 0.5。有意思的是n1000 时离 0.5 很近但到了 n10000单次结果反而偏得更远了一些。这并不违背大数定律。样本量增加后整体误差量级会下降但某一次随机实验并不保证单调接近理论值。图2 中心极限定理样本均值直方图方差分析的结果则可以直接手工复核。三组材料强度数据经过anova1得到F15.4p≈0.00015264根据原始数据重新计算组间平方和为 184.8组内平方和为 102MSB184.8/292.4MSW102/176所以F92.4/615.4和 Syslab 输出完全一致。这种题我觉得比较适合课堂实验先让软件给答案再把 ANOVA 表里的数字重新手算一次比单纯记公式更直观。优化部分反而发现了最值得看的问题优化模块包含 linprog、intlinprog、fminunc、fmincon、quadprog以及粒子群、遗传算法和模拟退火。线性规划返回x[2,6]最大利润360-1 背包返回[0,1,1]最大价值22都可以通过枚举直接验证。Ackley 函数的粒子群搜索也跑到了接近原点的位置目标值约为10⁻¹³Rastrigin 函数使用模拟退火则直接得到(0,0)目标值为 0。但第 28 题的 Rosenbrock 约束优化比较有意思。原脚本从[-1,2]出发fmincon 返回x≈(-0.9976,0.9951)f(x)≈3.9903我换成[0.5,0.5]重新运行却得到x≈(0.5022,0.2489)f(x)≈0.2489目标值一下差了约 16 倍。为了确认哪个更合理我又沿约束边界扫描了 2 万个点最低值同样约为0.248897位置就在 x₁≈0.5022 附近。图3 约束Rosenbrock初值敏感性这其实把局部优化的特点展示得很清楚求解器返回一个结果并不意味着已经证明它是全局最优解。对于这类非凸问题初值会直接影响搜索过程。实际使用时多换几个初值甚至配合全局搜索做验证比只看一次 fmincon 输出更稳妥。48 题里唯一没直接跑通的一题第 35 题是手写梯度下降。算法本身没有问题但脚本在 Julia 顶层循环中对变量x重新赋值触发了软作用域问题最终报UndefVarError: x not defined我把迭代过程封装进函数后重新运行得到x≈(2.24999,-4.74997)而解析最优点为(2.25,-4.75)两者非常接近。所以这一题的问题不是梯度下降算法而是 Julia 的变量作用域写法。对于刚开始写 Julia 的人来说这个报错反而挺有代表性。微分方程部分比想象中丰富最后 12 题从最简单的dy/dty一直做到热传导、SIR、Lotka-Volterra、时滞微分方程和洛伦兹混沌。其中 RK4 的实验比较适合观察数值方法的精度。步数从 10、20、40 增加到 80、160 后相邻两次误差之比逐渐接近16这正好对应经典 RK4 的四阶收敛特性步长减半后误差理论上大约缩小 2⁴16 倍。热传导案例也可以和解析解比较。数值计算在指定位置得到0.00724904解析结果约为0.00719188两者相差约5.7×10⁻⁵。而洛伦兹系统则更适合看可视化。σ10、ρ28、β8/3 时可以直接画出比较典型的三维洛伦兹吸引子。图4 洛伦兹吸引子三维相轨迹跑完 48 题之后的一点感受这套题库给我的感觉不像传统的“48 道练习题”。它更像是把数学课里经常手算的东西分别用 Julia 又实现了一遍高数可以比较符号解和数值解概率统计可以观察随机波动优化问题可以检查求解器结果微分方程则可以继续看误差和动态过程。而且真正逐题运行后也能发现一些参考答案之外的问题泰勒展开的 Order 参数和教材里的“阶”并不是完全相同的概念局部优化对初值敏感Julia 顶层循环还有软作用域问题随机类题目则不应该期待每次得到完全相同的数字。这些地方反而比“48 道题全部得到标准答案”更有意思。如果正在学习 Julia 科学计算或者想把高数、概率统计、优化、微分方程中的一些公式变成可以直接运行的程序这套题可以作为一组比较集中的练习。本文使用的是 MoHub 上的《数学试题Syslab 科学计算 48 题》仓库地址https://mohub.net/model/26417/summary
