MathScript · v1.0.0 预发布

一个 C++23 库,从 LU 到 CFD

工程软件跑在很重的数学上,而几乎没人自己写这些数学。它是用别人的库和收费平台拼起来的 — 难审计,难改动,在不联网的构建机上还难安装。MathScript 自己把这些数学做了,从矩阵运算一直到流体力学,装在一个什么都不用取的 C++ 库里。

语言C++23
测试套件816 个 CTest
覆盖率关卡90%
静态库35
最近一次推送不久前
两个决定了一切的决策
  • 树内自带矩阵内核。 基础线性代数子程序(BLAS)和线性代数软件包(LAPACK)在这里是自己实现的,不是取来的:不用 Eigen,也不用 OpenBLAS。 linalg 拥有 LU、QR、奇异值分解(SVD)、eig、Cholesky 以及 LAPACK 风格的那些内核,所以部署是一次编译,而不是一场找依赖的搜捕。
  • 一个受限的 C++ 子集。 不用裸指针,不用异常,不用不安全的类型转换 — 编译期强制。生产代码返回 Result<T>,所以错误处理是确定性的,而且在类型里看得见。
大白话

一分钟说清这是什么

问题所在

应力、流动、信号、风险 — 工程软件底下那些计算,很少是交付它的团队自己写的。它们来自十几个外部库和收费平台,得取下来、买授权、还得信得过。一旦答案看着不对,推导过程在别人的代码里;在一台封闭的构建机上,你可能连取都取不下来。

解决办法

MathScript 是一个自己做数学的 C++ 库:线性代数、统计、微分方程、有限元、流体流动、优化,还有一个符号代数系统,分在三十五个静态库里。大多数项目从 BLAS 和 LAPACK 引入的那些矩阵例程,这里是自己写的。Windows 构建上全部 816 个测试套件通过。v1.0.0 还没发布。

这是给谁用的

构建机上不了网的团队 — 国防、医疗、航空航天、银行 — 在那里每取一个依赖就多一道审批。真正的活用 C++ 干、数学却用 Python 干的产品,也因此背着两套问题。以及想看到方法被写出来、能读得到的教师和学生。

数学在代码树里,不在依赖清单里。 这就是论点,本页余下的部分是证据:三十五个库里装了什么、为什么失败是从返回类型里回来而不是抛异常,以及那些测试数字到底覆盖了什么。
交互演示

一个在你浏览器里跑的符号计算机代数系统(CAS)

输入一个表达式。它会被切成词法单元、解析成抽象语法树(AST)、做符号求导、化简,然后为作图做数值求值 — 同时在可见区间上做一次辛普森法则积分和一次二分法求根。

mathscript-repl

f(x) =
f(x) f′(x),符号形式 f 的根

符号导数


          
定义域上的 ∫
—
找到的根
—
AST 节点数
—
解析
—

Result<T>

Ok
解析和求导都没有出错。

支持: + - * / ^, sin cos tan exp log sqrt abs sinh cosh tanh asin acos atan,常量 pi 与 e。真正的 CAS 要大得多;这里是同一个想法,缩到读得下的规模。

为这个页面写的分词器、递归下降解析器、符号求导器和化简器。C++ 实现在 symbolic 库里。
不是重新实现一遍

真正的那个 C++ 库,编译成了 WebAssembly

上面的一切都是为这个页面写的 JavaScript — 它是老实的,但只是真东西的一个模型。下面才是真东西: libms_symbolic 本身,由构建本地库的同一份源码编译而来,在你的浏览器里运行。

ms::sym_diff — WebAssembly

未加载

你不按加载就什么都不下载,按了也只取一次。这个模块是 113 千字节(KB)的 WebAssembly 加 10 KB 的加载器 — 完整的库构建是 4.9 兆字节(MB),所以这里只链接了这四个调用能够到的部分。面板上显示库的版本,以及这份构建报告出来的向量指令集架构(ISA)。

化简后
—
导数
—
积分
—
库
—
向量指令集
—
指令集那一行是这个库在如实报告自己。 它调用的是 ms::detect_isa(),和它在本机上发起的是同一个调用。在你的桌面机上,它会回答高级向量扩展(AVX2 或 AVX-512)里的一种;在这里只有一种向量 ISA,它就照实说。
用 Emscripten 从 MathScript 代码树构建。为此不得不修掉三个可移植性缺陷,这三个也都影响 Apple clang 和 ARM 上的本地构建 — 见 tools/wasm/README.md.
范围

三十五个静态库,六个领域

稠密与稀疏线性代数、特殊函数、统计和机器学习(ML)。常微分方程(ODE)和偏微分方程(PDE)、有限元方法(FEM)与计算流体力学(CFD)。优化、信号与图像处理、数论、图、几何、拓扑、量子原语、控制、金融、压缩 — 外加一个符号 CAS。LU、QR、SVD、特征值求解器和 Cholesky 都写在树内。

六个库领域 — 核心系统、数值、统计与机器学习、应用、符号和专门领域 — 都建立在一条 Result<T> 基础轨道上,不用异常,也不用裸指针
滑动查看完整示意图 →
三十五个库,一套错误约定。 底下那条轨道才是关键:失败在返回类型里,而不是在你到栈顶才发现的那个异常里。
核心

核心系统

稠密与稀疏线性代数,LU、QR、SVD、特征值求解器和 Cholesky 都在树内。 Result<T> 错误处理贯穿始终。

数值

ODE、PDE、FEM、CFD

时间积分、有限元和计算流体力学,外加特殊函数与数值积分。

统计

统计 & 机器学习

分布、推断、回归,以及它们底下那套最优化机制。

应用

信号、图像、控制、金融

变换、滤波、图像处理、控制理论和量化金融原语。

符号

计算机代数

一个小的符号计算 CAS,和数值部分并排放着,而不是拴在它们上面。

专门领域

图、几何、拓扑、量子

数论、图算法、计算几何、拓扑和量子原语。

对外暴露的东西

三个可执行文件,其余一切都可选

三个可执行文件之外的一切都是构建选项 — 一个 Qt 图形用户界面(GUI)、CUDA、消息传递接口(MPI),以及一个即时编译器(JIT),建在 LLVM 的按需编译(ORC)层之上。

mathscriptc编译器 / 批处理驱动
mathscript-repl交互式会话
mathscript-server服务模式
可选Qt 图形界面、CUDA、MPI、LLVM ORC JIT
验证

816 个套件能买到什么

下面这些门禁背后的持续集成(CI)矩阵覆盖两个编译器:Windows 上的 Microsoft Visual C++(MSVC),以及 Linux 上的 GNU 编译器套装(GCC)13。

关卡设定
CTest 套件816 个,100% 通过
平台Windows MSVC Release
CI 矩阵MSVC + Linux GCC 13
覆盖率关卡90%
消毒器已启用
模糊测试已启用
基准回归28 个,容差 10%
预发布就是预发布。 v1.0.0 还没有发布。816 个套件这个数字来自 Windows MSVC Release;Linux GCC 13 那一路也在 CI 里跑,但拿出来当主数字的是 Windows 上测到的那个。
这是给谁用的

给程序员的一整套数学工具,就一件东西

正经的计算工作通常意味着把十几个各自独立的软件拼在一起,然后指望它们说法一致。这是一个把这些全都覆盖到的库。

01

不被允许下载任何东西的团队

国防、医疗、航空航天和银行的构建系统常常与互联网隔离。这里的东西全部自带,所以没有要下载的,也没有要报批的。

02

厌倦了把 Python 拴在产品上的团队

很多软件用一种语言干正事,用另一种语言算数学,于是有了两套麻烦。这个让数学和产品待在同一种语言里。

03

教学与学习

方法是完整写出来、可以读的,而不是藏在某个供应商封好的组件里。学生能跟上实际发生的事。

在这里看到你自己的情况了吗? 它现在已经开放测试,而它是为哪些人做的,那些人的反馈才是真正会改变它的。 成为测试用户 →
为什么不用异常

一个不会朝你扔异常的数值库

数值代码失败的方式都很平常:矩阵奇异、迭代不收敛、特殊函数里的定义域错误。用异常来发这个信号,意味着每个调用方要么把所有东西都包进 try ,要么在栈顶发现失败,却没有任何上下文。MathScript 把失败做成返回类型的一部分。

// Every production entry point returns Result<T>.
auto lu = linalg::lu_factor(A);
if (!lu) return lu.error();          // singular — handled, not thrown

auto x = lu->solve(b);
if (!x) return x.error();

// No raw pointers, no unsafe casts, no exceptions:
// the restricted subset is enforced at compile time.