26

有没有用函数式编程语言制作的严肃的科学数学库?从函数式语言的本质来看,人们会认为它们特别适合数学,但众所周知的算法似乎是程序性的。

例如,经典的数字食谱系列几乎是以程序方式编写的。LAPACK在许多领域几乎是事实上的标准,但它是在 Fortran 中,因此是程序性的,或者可能是 OO,但绝对不是功能性的。

有没有人能够将这些众所周知的程序算法转换为函数式风格?

更新:似乎函数式语言被用于符号计算,例如在 Mathematica 中。但是,是否存在与数值计算和函数算法本质上不兼容的东西?或者仅仅是因为命令式算法恰好是首先发明的,所以没有人费心想出功能等价物?

4

7 回答 7

24

hackageDB 中有一个用于数字内容的 Haskell 库:hmatrix。它来自 LAPACK、BLAS 和 GSL(GNU 科学图书馆)。

但是您应该记住,命令式算法可以很容易地使用 monad(更具体地说,状态转换器)转换为纯函数式语言。事实上,任何有效的就地实现通常都必须使用这种机制来在纯函数式语言中提供可变变量。

至于遵循功能风格,在很多情况下是不可能的。对于许多问题,没有任何已知的(有效的)函数方法。当然,例如,您可以让此类算法在 Haskell 中运行,但它们看起来与使用 Matlab、Fortran 或 C 编写的算法没有太大区别。

编辑:

这既是明显的不兼容,也是首先出现的问题:

  1. 高效的数值算法通常需要可变数据。虽然这在纯函数环境中是可能的,但它不像在命令式语言中那样简单。但是这两种计算模型是完全等价的。
  2. 底层机器(例如指令集)一直是并且仍然是必不可少的,只有极少数例外(!)。考虑到真实机器的建模方式,命令式编码算法更容易分析和优化。
  3. 虽然基础数学允许相对容易地推导函数解决方案,但您不会获得有效的算法(就像直接从数学推导命令式解决方案的情况一样)。由于大多数努力已经并且仍然是针对命令式解决方案的,因此功能对应物根本不为人知。我所说的功能对应物是指正确表达功能意图和风格的代码。
  4. 有很多可以重用的命令式代码。其中大部分可以使用状态转换器转录成函数式语言,尽管它看起来仍然很有必要。

我实际上认为像 Haskell 这样的纯函数式语言可能对编码算法有益:可以在同一块代码中统一数学描述、算法本身和某种面向类型的证明(即使用Curry-Howard 同构) .

于 2009-06-08T18:45:17.570 回答
7

我会使用 LAPACK 作为函数式语言的黑匣子,而不是尝试重写它。几十年来,LAPACK 已经被一些非常聪明的人测试、微调、优化等。我不会碰它。

于 2009-06-08T22:20:44.547 回答
5

本着优秀的计算机程序结构与解释的精神,还有经典力学的结构与解释。本书使用 Scheme 阐明了力学变分方法中使用的许多松散的数学符号。

本书的基石是scmutilspackage,其中包括许多计算任务的功能方法,例如集成和最小化。

于 2009-06-08T20:04:00.533 回答
5

好问题!

几年来,我一直是该领域的少数先驱之一,我们直到最近才达到可以同时获得类似 Fortran 的性能和类似 Python 的简洁性来解决各种问题的地步。在详细检查了所有可用的函数式语言及其实现之后,我决定将精力集中在静态类型的不纯函数式语言上:开源OCaml 编程语言和Microsoft用于 .NET的 F# 编程语言。

我的《OCaml for Scientists 》一书涵盖了使用 Linux 或 Mac OS X的OCaml 编程语言的科学计算。我的《科学家的 F# 》一书涵盖了使用 Windows 和 Visual Studio的 Microsoft F# 编程语言的科学计算。我的公司还销售F# for NumericsF# for Visualization库,它们完全用 F# 编写,并在内部广泛使用函数式编程以提高简洁性、清晰度和可维护性,并在外部使库更易于使用。例如,一流的函数可以让您非常轻松地绘制图形,例如绘制正弦函数:

Plot([Function sin], (-5., 5.))

F# for Visualization 甚至会尝试可视化任何类型的任何值,因此您可以给它一个任意精度的有理数矩阵,并将结果显示为排版 math

我们在 OCaml 和 F# 语言中以函数式风格编写科学计算代码取得了巨大成功。特别是,F# 可以轻松编写通用的高性能并行代码,而不会对抽象造成任何性能损失。因此,您可以实现适用于任何类型(单精度、双精度、复杂甚至符号!)矩阵的 QR 分解,甚至可以击败英特尔 MKL 等供应商调整库的性能

最后,我应该指出,Mathematica 早在我之前就在某种程度上开辟了这条道路。然而,他们的解决方案是将用 C 语言编写的庞大的数值和符号函数标准库与传统的命令式风格相结合,并提供一种相当基本的函数式编程语言来调用这些函数。他们的方法的主要缺点是用 Mathematica 编写的通用代码(即,时间主要不是花在他们的标准库中)比 C 慢大约 1,000 倍。

于 2009-07-31T13:42:46.253 回答
4

一些计算机代数系统(例如 Maxima)在内部使用基于 LISP 的语言来表示符号计算/语法树。

数学函数式语言的例子:

http://en.wikipedia.org/wiki/J_(programming_language)

http://en.wikipedia.org/wiki/K_(programming_language)

无论如何,有几个数学问题和算法在函数式风格中不能很好地表达或有效。一个有效的实施总是必不可少的。例如:埃拉托色尼筛

于 2009-06-08T18:50:36.110 回答
3

我相信mathematica 使用它自己的函数式语言。

于 2009-06-08T18:35:58.323 回答
3

定义“严重”。请记住,函数式语言(LISP 除外)是相当新的——Backes 的原始论文只是在 70 年代后期,而生产工程函数式语言是相当新的。众所周知且广为接受的数值包均基于 60 年代末和 70 年代初开始的算法和代码 — BLAS于 1979 年首次发布。因为,对于生产用途,人们倾向于使用知名且值得信赖的包,对旧的 FORTRAN 代码有很大的推动作用。

但是肯定有人用函数式语言进行数值处理。正如在另一个答案中指出的那样,Mathematica 越来越成为一种函数数字语言,并且越来越多地在其自身中实现。

于 2009-06-08T18:58:00.150 回答