Matlab、Julia与Python之间的对比 | Toby Driscoll


我已经使用MATLAB超过25年了,虽然这不是我学习编程第一种语言,但凭借它我得以进入数学方法时代,了解MATLAB对我的职业生涯非常有益。
但是另外一方面,Python在科学计算中的崛起已经不可忽视,MathWorks肯定有同样的感受:它们不仅增加了从MATLAB中直接调用Python的能力,而且还采用了一些语言特性,例如对二元运算符的操作数进行更积极的广播
这已经达到了我一直质疑我在研究和教学中继续使用MATLAB的程度,虽然大部分对于我来说很容易,我也为此投入了大量的精力,但很难激起真正我学到新东西的动力。
我编写过基于MATLAB的教科书,这本书有40多个函数和160个计算实例,它涵盖了我认为使用MATLAB进行数值科学计算的全面基础,我今年开始将代码翻译成JuliaPython。这种经历使我对与科学计算相关的三种语言有了特殊的看法,我试图在下面进行讨论。
我将主要讨论成本和开放性问题,MATLAB与Python和Julia不同,既不是无啤酒也不是无语音。当你把成本放在一边时,这些语言之间的许多差异的有用框架在于它们的起源。MATLAB,最古老的,优先考虑数学,特别是数字导向的数学;Python于20世纪80年代末开始,它以计算机科学为中心;Julia从2009年开始在这些方面之间取得更多平衡。

MATLAB
最初,MATLAB中的每个值都是一个双精度浮点数的数组。数组和浮点两个都是灵感的设计决策。
用于浮点的IEEE 754标准直到1985年才被采用,并且内存是用K而不是G测量的。浮点双精度不是表示字符或整数的最有效方式,但它们是科学家,工程师和越来越多的数学家想要在大多数时间里使用。此外,不必声明变量,也不必显式分配内存。让计算机处理这些任务,并将数据类型放在一边,释放你的大脑,思考对数据进行操作的算法。
数组非常重要,因为线性代数中的数值算法以LINPACKEISPACK的形式出现在自己的数组中。但是,使用科学计算中的标准承载FORTRAN 77访问它们是一个多步骤过程,涉及声明变量,调用隐式命名例程,编译代码,然后检查数据和输出文件。写一个矩阵乘法A*B并立即打印出答案是一个改变游戏规则的人。
MATLAB还使图形变得简单且易于访问。没有任何特定于机器的低级调用库,只是plot(x,y),还有更多的创新,例如baked-in复杂的数字,稀疏矩阵,构建跨平台图形用户界面的工具,以及前沿的ODE求解器套件,使MATLAB 成为以思维速度进行科学计算的地方。
然而,对于交互式计算而言,理想的设计,即使是冗长的计算,并不总是有助于编写好的和高性能的软件
在许多函数之间移动数据需要处理大量变量并经常查阅有关输入和输出参数的文档。平面命名空间中每个磁盘文件的一个功能对于一个小项目来说非常简单,但对于大型项目来说却是一个令人头痛的问题 如果您想避免速度瓶颈,则必须应用某些编程模式(矢量化,内存预分配)。科学计算现在被应用于更多的域,具有大量不同的本地类型的数据。等等。
MathWorks通过继续在MATLAB中进行创新来做出回应:内联函数,嵌套函数,变量闭包,众多数据类型,面向对象的特性,单元测试框架等等。每项创新都可能是解决一个重要问题的方法。但是,40年这些变化的积累产生了影响概念简单性和统一性的副作用。在2009年,我写了一本书,在不到100页的篇幅中,我很好地涵盖了我认为MATLAB的基本内容。据我所知,所有这些东西仍然可用。但是现在你需要了解更多才能称自己为精通。

(banq评:MATLAB只靠数据结构和算法打天下的套路已经不够用了,需要加入模式等面向对象或函数语言的设计要素)

Python
从某种意义上说,Python的历史似乎几乎是MATLAB的镜像。两者都具有交互式命令行,并且不受变量声明和编译的影响。但MATLAB是作为数值分析师的游乐场而创建的,而Python是在考虑黑客的情况下创建的。然后通过修订和扩展,每个人都向其他受众发展。

在我看来,Python仍然缺乏数学吸引力...

除了小烦恼之外,我发现Python + NumPy + SciPy生态系统变得笨拙且不一致。尽管语言主要用于面向对象,但存在一个矩阵类,但它的使用不鼓励并且将被弃用。也许MATLAB只是腐蚀了我,但我发现矩阵是一种足够重要的对象类型,面向对象OOP不是它的主要卖点吗?

在这些地方,数字生态系统对我来说看起来有点薄弱!...

一些专家认为,Python代码难以跟上编译语言的执行速度...

我想我明白为什么Python对科学计算领域的许多人来说都是如此令人兴奋。它具有一些MATLAB-ish语法和功能。它有很好的工具,可以很好地与其他语言和计算领域配合使用。它提供了免费且具有更好的长期可重复性。很明显,它适用于许多可能没有理由改变的人。

但是对于我这样已经知道如何在科学计算中编程的人来说,Python更像是一项学习使用的苦差事(banq注:习惯数据结构算法的实用主义想改变很难)。我们暂时不会知道它是否会继续席卷整个社区,或者已经接近顶峰。我没有特殊的预测能力,但我对它未来看跌。

Julia
Julia有一个后来者的优点和缺点。我赞赏朱莉娅的创作者认为他们可以做得更好
我们想要一种开源的语言,拥有自由许可。我们希望C的速度与Ruby的活力。我们想要一种同色的语言,像Lisp这样的真正的宏,但是有一些明显的,熟悉的数学符号,比如Matlab。我们想要一些像Python一样可用于通用编程的东西,像R一样易于统计,像Perl一样自然地用于字符串处理,像Matlab一样强大的线性代数,擅长将程序粘合在一起作为shell。一些简单易学的东西,但却让最严重的黑客感到高兴。我们希望它是交互式的,我们希望它被编译。

在很大程度上,我相信他们已经取得了成功。在1.0版本的后期,他们似乎略微淡化了REPL,并且有一些几乎无偿的离开MATLAB的教堂。(LinRange和linspace 究竟哪个更好?)但这些都是狡辩。

这是我使用的第一种超越ASCII的语言。使用变量ϕ和运算符之类的我仍然会得到不合理的满足感≈。它不仅仅是化妆品; 能够看起来更像我们写的数学表达式是真正的加号,虽然它确实使教学和文档有点复杂化。

使用Julia工作让我觉得我选择了一些编程习惯,因为MATLAB的选择,而非内在的优越性...

多重调度的一大特点使得某些事情比面向对象更容易和更清晰。例如,假设您使用传统的面向对象语言的Wall和Ball类。哪个类应该放入Wall与Ball的碰撞行为呢?或者你需要一个Room类来扮演裁判?这些问题可以让我分心。使用多个分派时,数据将打包到对象类型中,但对数据进行操作的方法不会绑定到类。

function detect_collision(B::Ball,W::Wall)

了解类型,但是它们是独立定义的。我需要花费大量的编程来理解多重调度的概念对于扩展语言有多么有趣和潜在重要。

我还没有看到Julia承诺的超过MATLAB的速度提升。部分原因是我的相对缺乏经验和我所做的任务,但部分原因还在于MathWorks在自动优化代码方面做了不可思议的工作。无论如何,这不是我在大多数时间关注的编码方面。

我使用了Julia编程花一段时间之后才感到舒服(也许我只是变老了)。它让我对数据类型的思考超出了我的想象,并且总是潜在地怀疑我错过了正确的方法来做某事。但是对于日常使用,我现在几乎可以转向Julia,将其作为MATLAB使用。

底线
MATLAB是企业解决方案,尤其适用于工程。对于基本的数字任务来说,这可能仍然是最容易学习的。细致的文档和数十年的贡献学习工具绝对重要。
MATLAB是科学计算世界的宝马轿车。这是昂贵的,那是在你开始谈论配件(工具箱)之前。您需要为坚如磐石的,平稳的性能和服务付出代价。它也吸引了不成比例的仇恨
Python是福特的皮卡。它无处不在,受到许多人的欢迎(在美国)。它可以做你想做的一切,它是为了做一些其他车辆无法做到的事情。你偶尔会想要借一辆。但它并没有提供很好的纯粹驾驶体验。
Julia是特斯拉。它建立了一个改变未来的大胆目标,它可能会。它也可能只是一个脚注。但与此同时,你会得到你的风格,并有足够的力量。