【问题标题】:Porting Mathematica to Octave将 Mathematica 移植到 Octave
【发布时间】:2011-12-14 16:01:40
【问题描述】:

我必须将大量文件从 Mathematica 移植到 Octave。 我找到了Lisp Mathematica parser from ~1991,但我对 Lisp 不是很熟悉,所以我想知道是否有人在这个方向有任何移植经验。 在研究并向 WolframAlpha 发送电子邮件并没有实际结果后,我将不得不使用 Lex 和 Yacc 来生成交叉编译器。这对我来说似乎有点过分了。

任何提示或指针将不胜感激。

澄清:

我从很多 Mathematica 文件开始,它们的功能必须移植到 Octave。我只是想在尽可能短的时间内实现这个目标,因为这是我老板在假期交给我的任务。 感谢您的帮助,我将查看 FullForm 并检查 Mathematica 文件中的非便携式内容。 如果只能转换一定数量的文件,我将不得不手动完成其余的工作,这需要一些时间。因此,从一个程序转移到另一个程序基本上是一次性的事情。

正如 Leonid 的帖子中提到的,这项任务似乎有些过分,但我是一名学生研究助理,这正是我必须在我的部门完成的任务。

【问题讨论】:

  • Mathematica 和 Octave 完全不同,我确信自动转换是不可能的。你能更详细地描述你需要什么吗? C 中的 Mathematica 解析器? FullForm 表达式的解析器相对容易编写,您可以使用 Mathematica 将所有内容转换为 FullForm。但我认为你应该先让你的问题更清楚。
  • 为什么看起来有点过分?如果文件只包含简单的表达式,那么它应该很简单,否则它可能会在八度音程中有效地重新实现mathematica。

标签: parsing compiler-construction wolfram-mathematica octave parser-generator


【解决方案1】:

我经常使用 MATLAB(Octave 的 $$$$ 版本)和 Mathematica,而且我非常有信心实现一个自动从 Mathematica 转换为另一个的解析器/移植器。首先,MATLAB/Octave 不支持模式匹配、术语重写或函数式编程,所有这些都是 Mathematica 中最常见和最佳的编码风格。

例如,考虑纯函数(Mathematica)

f = #^2&;

在 MATLAB/Octave 中确实没有这样的等价物。匿名函数足够接近,您可以将其写为 (MATLAB/Octave)

g=@(x)x.^2;

但是,Mathematica 会以符号方式对您传递给函数的任何内容进行平方,而 MATLAB 仅适用于标量/向量/矩阵。因此,即使遇到纯函数,也无法在不了解传递给纯函数的内容的情况下自动将其重写为匿名函数。

MATLAB/Octave 中缺少的另一个概念是mathematica 中的惰性求值/SetDelayed:=。所以如果你的纯函数是

f := a #^2 &;

那么,f 在调用f 时使用a 的值。但是,将其编写为匿名函数:

g = @(x)a*x.^2;

会在定义时捕获a的值,形成一个闭包。我在this answer of mine提供了一个更好的例子

如果您有一个主要以 Mathematica 中的程序风格编写的代码库,那么从理论上来说,可能可以转换为 octave。但是,我很难想象一个严肃的 Mathematica 项目完全以程序方式编写。简而言之,需要人类以每种语言的惯用方式来翻译逻辑


最后,如果您只是想将表达式从 Mathematica 转换为 MATLAB/Octave,那么您可能需要查看 ToMatlab 包。我经常使用它来转换 Mathematica 中计算的表达式,以便在 MATLAB 中的不同代码库中使用。一个简单的例子是:

expr = Sin[x + x^3] + ArcSin[y];
ToMatlab[expr]
Out[1]= sin(x + x.^3) + asin(y)

【讨论】:

    【解决方案2】:

    您不需要 Mathematica 解析器来移植。您需要在 Mathematica 中编写移植程序并重用 Mathematica 自己的解析器。这与SymbolicC 的方向相同。如果我是你,我会构造一些 Mathematica 子语言(称为 SymbolicOctave),带有完全惰性的头部,然后编写一个名为 say ToOctaveCodeString 的函数。您可以参考 SymbolicC 的实现,了解 C 是如何完成的 - 它在 Mathematica 发行版中可用。

    第二个也是最复杂的部分是编写一个从 Mathematica 代码子集到这个惰性SymbolicOctave 表示的转换器。这部分真的很重要,因为(大概)Mathematica 语言有很多 Octave 语言本身不支持的特性,你必须在 Octave 中实现这些特性。在这里,您还需要使用某些技术来使用 Mathematica 生成 Mathematica 代码,我在 this answer 中描述了其中一种。这一切都假设您可以访问 Mathematica。

    说了这么多,如果有这样的选择,我会放弃一般任务而只使用 Mathematica。这项任务似乎只适用于 Mathematica 的一个非常狭窄和特殊的子集,即使那样也不是微不足道的。如果可以选择链接 Mathematica 并从 Octave 使用它,而不是将所有内容移植到 Octave,我会这样做(从技术上讲,这应该很容易做到)。如今,即使是完整 Mathematica 的商业许可的成本也相当低(与竞争产品相比,尤其是考虑到类似于 Octave 的产品),考虑到创建转换器的开发成本,它在财务上也可能是一个更好的选择这将是任何好处。

    【讨论】:

      【解决方案3】:

      从 Mathematica 为功能较弱的系统生成代码的惯用方法不是使用第三方工具(它应该与 Mathematica 核心一样强大),而是使用 Mathematica 本身。

      这种类型的一些代码生成器已经开箱即用(用于 C 和 Fortran),看看它们是如何实现的,然后将它们重新定位到 Octave/Matlab。

      【讨论】:

      • 我原则上同意,但是对于那些还不了解 mma 并且必须在假期这样做的人来说,这似乎过于雄心勃勃,而且有些东西可能根本无法翻译(考虑 NDSolve)。但我可能是错的,我从未尝试过。
      • 我将选择一个选项并尝试转换一些代码,看看转换所有内容需要做多少工作。然后我可以看看它是否可能,并可以向我的老板提供反馈。
      • @acl,使用这种方法,Mathematica 不会转换所有内容(这绝对是不可能的),但它可以象征性地解决可能解决的问题,并生成适合执行的数值算法水平语言(如 C 或 Matlab)。当然不能一味的转换,应该是人工辅助的过程。
      • 是的,我很感激。但是,除非要移植的代码是 a) 不是代码,而只是表达式,b) 命令式代码,否则我无法想象这甚至可以半自动地完成。如果它是命令式代码(例如可以由Compile 自动编译为 C,那么设置它以便将其转换为 matlab 看起来并不简单。我不是否定的,只是想给@wikke 一个想法这涉及到什么。但当然,在他的情况下,这可能比听起来容易。
      • @acl,我怀疑尝试将整个笔记本“移植”到 Octave 没有多大意义。很可能只需要生成 N[...]NSolve[...]NDSolve[...] 等中的代码,其余代码由 Mathematica 自己解释。