GNU Octave 的目标就是制作一款类似 MATLAB 的开源数学软件,在它的 bug tracker 分类里就直接有一项: Matlab Compatibility ,维基百科里也说可以认为这就是一个“ Software Clone ”。然而事实上,通过在这学期的 Numerical Analysis 课程中使用 Octave 替代 MATLAB 的经历,发现两者不兼容的地方还是有很多的。总结起来就是,不要对 portability 抱有太大幻想,几乎所有大型 MATLAB 都需要人工修改才能 port 到 Octave 上。

Octave 官方 wiki 里有专门章节介绍里两者的不同之处: Porting programs from Matlab to Octave

基本语法方面 Octave 几乎完全兼容 MATLAB 脚本,而且有意地提供了一些附加语法,可以参见维基百科的这个章节。总的来说 Octave 加的这些语法糖都更符合直觉,我在不知道的情况下使用里不少,导致写出来的脚本不能在 MATLAB 里跑……

绘图方面目前有两个后端: fltk 使用 OpenGL 加速,性能好但是功能略差,尤其是文字渲染很糟糕, 3D 图形的旋转拖拽很难用; gnuplot 功能强不少,图也漂亮一些,但在重度绘图时很卡。不论哪个后端,画出的图都不可能和 MATLAB 完全相同,尤其是对文字的处理。不过考虑到绘图本来就是“示意”,问题也不算大。

MATLAB 有一种专有的 .p 文件,是经过解释、混淆后的二进制脚本。不必说,这类文件肯定是 Octave 无法支持的,也是没有办法的事情。

最大的不兼容性是发生在一些“智能”、“高级”函数上。最简单的例子包括使用反斜杠运算符进行高斯消元。听起来很简单,但学过 NA 的就知道其中有不少坑和高级算法。看 MATLAB 官方文档中的 algorithm 就知道,这个“基础”功能其实是相当“智能”的—— MATLAB 会根据矩阵的特性选择适当的算法。即使有文档、这些算法也都是公开的,但具体的判断标准、参数选择以及小优化都是不知道的,甚至 MATLAB 自己也会不断更新升级。就结果而言,如果你的线性系统够复杂、精度要求很高,最后得到的答案很有可能有细微不同,并且在后续计算中进一步被放大。

再举一族函数—— quad ,即数值积分。这族函数在两个程序里的表现非常不同,先说使用的算法: MATLAB 是 adaptive Simpson quadrature, Octave 是 Gaussian quadrature 。 Octave 中就没有使用 adaptive Simpson quadrature 的数值积分函数,而 MATLAB 中也没有使用原始 Gaussian quadrature 的函数(只有 quadl ,使用 Gaussian quadrature 的变体 Lobatto rule , Octave 中的这个函数也是使用该算法)。这些算法有各自不同的特点,不同“形状”的曲线适用不同的算法,精度、速度都有很大不同。而且,两个程序中 quad quadl quadgk 等函数的参数列表和返回值形式竟然都不一样!

MATLAB 打算在将来弃用 quad ,而改用类似高斯消元的做法,使用一个充满黑魔法的 integral 函数,把这些算法细节都隐藏起来。可以想见,到时候 Octave 想要模仿行为就更加困难了。而且数值积分的误差是比线性方程要大得多的,实现细节的区别在结果中很容易就能反映出来。

总而言之,不要抱着写出能够兼容两个平台的代码的想法,从一个平台切换到另一个平台也需要经过仔细的检查;以及如果需要和业内的其他人交流、协作代码,那么最好还是也用 MATLAB ,免得遇上麻烦。