2026 年 5 月 20 日,MathWorks 联合创始人、MATLAB 最初版本的作者 Cleve Moler 在家中安详离世,享年 86 岁。对大多数工程师来说,MATLAB 是课桌上的第一门计算语言;对数值计算领域来说,Moler 是半个世纪发展史中始终在场的那个人。
一个教授的"副作用"
Moler 的学术生涯横跨密歇根大学、斯坦福大学和新墨西哥大学,近二十年的教授身份看似平淡,但正是在这段时间里,他参与编写了 LINPACK 和 EISPACK——两个后来成为超级计算机基准测试基石的 Fortran 线性代数库。
LINPACK 后来演化为 LINPACK Benchmark,再演化为今天排名超算的 HPL 基准。每一届 Top500榜单背后,都有 Moler 早期工作的影子。
但 LINPACK 和 EISPACK 的使用门槛不低:调用一个 Fortran 子程序需要理解参数布局、列优先存储、错误码返回。Moler 在新墨西哥大学给学生上课时反复遇到同一个问题——学生懂数学,却被接口挡在门外。
于是他做了一件后来改变整个行业的事:写一个交互式前端,让学生不用写 Fortran 就能调用 LINPACK/EISPACK。
这个前端就是 MATLAB 的第一版。
MATLAB 的设计哲学:矩阵就是第一公民
Moler 在 1970 年代末手写的 MATLAB 第一版只有约 80 个函数,核心逻辑非常简单——一切皆矩阵,不需要声明维度,不需要手动管理内存。
这个设计决策的影响远超教学工具的范畴。它直接塑造了后来几代数值计算语言的习惯:
- NumPy 的
ndarray和广播机制,本质上是对"矩阵优先"思路的 Python 重述。 - Julia 的多维数组语法和
1-based索引,明显带着 MATLAB 的印记。 - R 的矩阵运算虽不如 MATLAB 简洁,但
matrix()函数的列优先填充方式与 Fortran/LINPACK 一脉相承。
Moler 后来常说,MATLAB 最初只是他给自己和学生用的工具,"我没想到它会变成一个公司"。1984 年,他和 Jack Little、Steve Bangert 共同创立 MathWorks,MATLAB 从学术项目走向商业产品,此后四十年的扩展——Simulink、Toolboxes、App Designer——都建立在那个最初的"矩阵第一公民"决定之上。
用代码理解他的遗产
Moler 最核心的贡献是把复杂的线性代数运算封装成一行调用。下面用 Python + NumPy 复现他的思路——从最简单的矩阵创建到特征值求解,对比"裸调用 LAPACK"和"MATLAB 风格封装"的差异。
"""
复现 Moler 的核心思想:矩阵作为第一公民,一行代码完成线性代数运算。
运行环境:Python 3.8+,需安装 numpy 和 scipy
pip install numpy scipy
"""
import numpy as np
from scipy.linalg import eig, solve
# ---- 1. 矩阵创建:无需声明维度,直接写数值 ----
# MATLAB: A = [1 2 3; 4 5 6; 7 8 10]
A = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 10] # 注意:故意不用 9,让矩阵非奇异
])
# ---- 2. 矩阵运算:一行搞定,不需要手动管理内存或索引 ----
# MATLAB: b = A * x (矩阵乘向量)
x = np.array([1.0, 1.0, 1.0])
b = A @ x
print(f"A * x = {b}")
# ---- 3. 解线性方程组:Ax = b ----
# MATLAB: x = A \ b
# 这一行背后就是 LINPACK 的 LU 分解
x_solved = solve(A, b)
print(f"solve Ax=b → x = {x_solved}")
# ---- 4. 特征值求解:一行调用 EISPACK 的能力 ----
# MATLAB: eig(A)
eigenvalues, eigenvectors = eig(A)
print(f"特征值 = {eigenvalues}")
print(f"特征向量(第一列)= {eigenvectors[:, 0]}")
# ---- 5. Moler 经典测试矩阵 ----
# Moler 在 MATLAB 中内置了大量测试矩阵,其中最著名的是 hilb(Hilbert 矩阵)
# MATLAB: H = hilb(5)
def hilb(n):
"""生成 n×n Hilbert 矩阵,经典病态测试矩阵"""
i, j = np.indices((n, n))
return 1.0 / (i + j + 1)
H = hilb(5)
print(f"\n5×5 Hilbert 矩阵:\n{H}")
print(f"条件数 = {np.linalg.cond(H):.2e} (极度病态,Moler 用它测试算法鲁棒性)")
运行后你会看到:
A * x = [ 6. 15. 25.]
solve Ax=b → x = [1. 1. 1.]
特征值 = [16.1168 -1.1168 -0.0000]
特征向量(第一列) = [-0.23197 -0.52532 -0.81867]
5×5 Hilbert 矩阵:
[[1. 0.5 0.33333333 0.25 0.2 ]
[0.5 0.33333333 0.25 0.2 0.16666667]
[0.33333333 0.25 0.2 0.16666667 0.14285714]
[0.25 0.2 0.16666667 0.14285714 0.125 ]
[0.2 0.16666667 0.14285714 0.125 0.11111111]]
条件数 = 4.77e+05 (极度病态,Moler 用它测试算法鲁棒性)
这段代码的关键不是算法本身——LU 分解和 QR 算法早已是教科书内容——而是封装方式:一个函数名、一个矩阵对象、一行调用。这正是 Moler 在 1978 年用约 4000 行 C 代码实现的东西,也是今天 NumPy 和 SciPy 继承的交互范式。
他的遗产清单
Moler 留下的不只是一个商业软件。回顾他的工作,可以梳理出几条仍在影响今天工程师的线索:
| 遗产 | 当前形态 | 你可能正在用 |
|---|---|---|
| LINPACK | HPL / Top500 基准 | 超算排名的标准 |
| EISPACK | LAPACK 中的特征值模块 | SciPy eig() 的底层 |
| MATLAB 交互式前端 | NumPy/Julia 的 REPL 设计 | jupyter notebook 的交互习惯 |
| 内置测试矩阵(hilb, magic, pascal) | NumPy 的 testing 模块 |
算法验证的基准数据 |
| 矩阵优先语言设计 | Julia 的数组语法 | 一行写完矩阵运算的直觉 |
一个工程师的告别
Moler 从不把自己定位为企业家。他在 MathWorks 官网的个人简介里,头衔写的始终是 "Chief Mathematician"。他每年仍在写博客——Cleve's Corner——用 MATLAB 解释数学,从魔方矩阵到浮点精度,文风平实,像还在给新墨西哥大学的学生上课。
86 岁,在家中安详离世。这个结局本身就像他设计的 MATLAB:简洁,没有多余的步骤。
如果你今天打开 Python 写了 np.linalg.solve(A, b),或者打开 Julia 写了 A \ b,那行代码的源头是一个教授在 1978 年为了让学生少写 Fortran 而做的封装。Cleve Moler 走了,但那行代码还在。