返回首页

我把数值分析教材做成了一个可交互工作台

发布于 2026-08-08 · 项目复盘 · 9 分钟

文章目录

项目地址:Numerical Analysis Studio

在线体验:https://math.gchkc.top

站内项目详情:Numerical Analysis Studio

今年 3 月,我发布过一版线性代数工作台。当时它解决的问题很直接:输入矩阵,计算行列式、逆矩阵、RREF 或分解结果,用来检查纸笔计算。

继续学习数值分析后,我发现“算出一个答案”远远不够。迭代法是否收敛?分解结果能否还原原矩阵?方程组的残差有多大?输入发生微小扰动时,结果会不会剧烈变化?这些问题才决定一次数值计算是否值得相信。

于是,原来的线性代数工具逐渐扩展成了 Numerical Analysis Studio:一个把计算、过程、验证和数据复用放在同一条工作流里的开源数值分析实验台。

数值分析工作台主界面

从一个计算器扩展成学习路径#

现在的工作台按数值分析的学习路径组织功能,而不是把几十个按钮堆在同一页:

  • 数值线性代数:矩阵运算、线性方程组、行列式、矩阵分解和特征分析。
  • 方程与逼近:非线性方程求根、插值和最小二乘逼近。
  • 积分与微分方程:复合求积、Romberg、Gauss-Legendre,以及常微分方程初值问题。
  • 误差与稳定性:条件数、输入扰动和相对误差观察。

这次扩展并不是简单地增加算法数量。更重要的变化,是让每个模块尽量回答三个问题:输入是否合法、算法得到了什么、这个结果可以怎样验证。

例如,线性方程组不只显示解向量,还会给出解的类型、秩和残差;矩阵分解会检查分解后的矩阵能否还原原矩阵;迭代算法会保留迭代历史、误差变化与收敛状态。遇到不适用的输入时,界面也应该解释失败原因,而不是只弹出一句“计算错误”。

为什么必须显示误差和残差#

符号计算容易让人形成一种错觉:只要页面显示了结果,结果就是精确的。但数值分析面对的是有限精度、近似方法和误差传播。同一个算法在不同输入上,可靠程度可能完全不同。

因此我单独加入了误差与稳定性模块。下面这个默认矩阵的一范数条件数为 77、无穷范数条件数为 60。用户还可以对矩阵 A 或线性系统右端向量 b 施加微小随机扰动,比较特征值或解向量的相对变化。

条件数与扰动分析界面

条件数不是一句“稳定”或“不稳定”的装饰性结论。它帮助使用者区分两类问题:究竟是算法实现错了,还是问题本身就对输入误差非常敏感。对学习工具而言,这种区分比多支持一种计算按钮更有价值。

把数学核心和界面状态分开#

项目使用 Next.js 16、React 19 和 TypeScript。页面组件负责输入、步骤展示与交互编排,主要数值逻辑则放在 src/lib 中,按领域拆分为独立核心:

src/lib/
  matrix-linear-system-core.ts
  matrix-decomposition-core.ts
  matrix-eigen-core.ts
  nonlinear-core.ts
  approximation-core.ts
  integration-core.ts
  ode-core.ts
  matrix-error-core.ts

这样组织有两个实际好处。第一,算法可以脱离 React 组件单独测试,不需要模拟点击页面才能检查矩阵分解是否正确。第二,界面改版时不用重写数学实现,新增展示方式也不会把状态处理混进算法函数。

项目同时使用 Math.js 和 fraction.js,但我没有把所有问题都交给第三方库。库适合承担基础数值与分数运算,具体的输入约束、方法选择、迭代记录、残差计算和错误解释仍然需要在自己的领域层完成。

矩阵库让结果真正可以复用#

如果每切换一个模块都要重新录入矩阵,工作台很快就会退化成一组互不相干的计算器。因此我用 Zustand 做了全局矩阵库,并通过 localStorage 保存数据。

一次运算的结果可以“存入库”,随后在方程组、分解或特征分析模块继续使用。矩阵记录不仅包含二维数据,还包含名称、类型、创建时间和唯一 ID。保存时会自动处理重名;读取旧版数据时,会校验矩阵形状并执行版本迁移,无法恢复的记录不会直接污染当前状态。

这部分代码并不涉及复杂数学,却显著改善了连续实验的体验。对工具型项目来说,算法覆盖面和工作流完整性同样重要。

用两层测试守住可信度#

数学工具最危险的问题不是页面崩溃,而是页面正常显示了一个错误答案。因此项目把检查分成两层:

  • scripts/math-tests 直接覆盖矩阵、非线性方程、逼近、积分和常微分方程等核心逻辑。
  • tests/ui 使用 Playwright 检查工作台回归、移动端导航、主题、符号键盘、可访问性以及各实验模块的关键流程。

目前仓库提供 typechecklinttest:mathbuildtest:ui 等完整脚本。数学回归负责回答“算法结果有没有变”,UI 测试负责回答“用户还能不能完成这次实验”。两者不能互相替代。

这次重构中的取舍#

项目当前仍有明确边界。浏览器端计算适合课程规模和中小型实验,不适合把超大矩阵当作专业科学计算任务直接运行;各模块的数学测试深度也还不完全一致。CSV、JSON 和 Markdown 导出尚未完成,算法说明仍需继续补充。

我暂时没有用“支持更多算法”掩盖这些限制。下一阶段更值得优先完成的是大规模输入的性能保护、按模块补齐回归用例,以及让实验数据能够稳定导出。它们会直接提高工具的可靠性和可迁移性。

写在最后#

Numerical Analysis Studio 从一个用来检查线性代数作业的小工具开始,逐渐变成了我理解数值分析和工程质量的实验场。做完这轮扩展后,我对“计算工具”的判断标准也发生了变化:它不应只给答案,还应该展示过程、暴露误差、说明失败,并允许结果进入下一次实验。

项目以 MIT 协议开源。如果你正在学习数值分析,可以直接访问在线工作台;如果你关心具体实现、发现了计算问题或希望补充测试,欢迎查看 GitHub 仓库并提交 Issue。

继续阅读

AI 工具链 · 2026-08-10 · 12 分钟

AI 小说编辑器架构拆解:从富文本工作台到上下文感知的流式生成

以 AI Novel Copilot 为例,拆解 Next.js、Zustand、Tiptap、Hono、SSE、Cloudflare D1 与 Drizzle 如何组成一套可持续演进的小说创作系统。

阅读全文 →

AI 工具链 · 2026-08-10 · 14 分钟

从 PDF 到可信回答:MindLink AI 的 RAG 全链路

拆解 MindLink AI 如何完成 PDF 解析、文本分块、Embedding、PGVector 检索、来源回传与流式回答,并分析这套 RAG 架构的取舍和演进方向。

阅读全文 →