如何从 R 调用 Fortran 程序

Sal*_*dor 5 interop fortran r

我对 Fortran 完全陌生,并且精通 R。我得到了一个巨大的 Fortran 程序,其中包含大约 30 个子例程和大约 15 个函数以及许多其他代码行。有人告诉我,我需要从 R 调用 Fortran 程序。我一直在网上寻找在 R 和 Fortran 之间创建这座桥梁的方法,但收效甚微。我可以从命令行成功执行 Fortran exe 文件并创建所需的输出。Fortran 文件名为“FortFish.f”

一个问题:

从 R 中,我是调用 Fortran 程序还是必须单独调用 Fortran 函数和子例程?

从 R 中,我是否像这样调用整个 Fortran 程序?:R CMD SHLIB FortFish.f 然后使用: dyn.load("FortFish.so")

如果我无法立即运行整个 Fortran 程序,我将根据要求发布几个小的 Fortran 函数和子例程。有谁有使用 R 和 Fortran 的运行示例可以分享吗?

我的 Fortran 代码非常大,否则我会把它贴在这里。谢谢。

小智 6

我看到三种可能性:

  1. 您单独编译 Fortran 程序,并使用 R 函数调用它system()。您必须以该程序可以读取的格式通过文件传递数据。

  2. 您编译一个从 R 加载的 DLL dyn.load(),然后使用 调用 Fortran 函数.Fortran()。您可以轻松传递数值数据(标量、向量或数组),但字符串数据更难处理。并且数组被复制

  3. 这种调用 DLL 函数的机制被认为过于简单,现在.Call()是首选,但要使用它,.Call()您必须编写 C 包装器。

我将举第二种可能性的例子。考虑 Fortran 中的一个子例程,它通过 Horner 算法计算多项式:

subroutine horner(n, a, x, y)
    implicit none
    integer :: n, i
    double precision :: a(n), x, y

    y = a(n)
    do i = n - 1, 1, -1
        y = y * x + a(i)
    end do
end subroutine
Run Code Online (Sandbox Code Playgroud)

从命令行编译:

R CMD SHLIB horner.f90
Run Code Online (Sandbox Code Playgroud)

从 R 调用它:

dyn.load("horner.dll")

horner <- function(a, x) {
  .Fortran("horner", as.integer(length(a)), a, x, y=0)$y
}

horner(c(-2, 0, 1), 1.414)
Run Code Online (Sandbox Code Playgroud)

如果您希望 Fortran 子例程将某些内容打印到 RStudio 控制台,您需要执行以下操作(至少在 Windows 上):

Sys.unsetenv("GFORTRAN_STDOUT_UNIT")
Sys.unsetenv("GFORTRAN_STDERR_UNIT")
Run Code Online (Sandbox Code Playgroud)

这确实是一个微不足道的例子,更复杂的程序将需要更多的工作,但你明白了。


如果您的 Fortran 程序是独立的(它有一个“程序”单元,并且应该编译为从命令行调用的可执行文件),并且如果您是 Fortran 新手,我建议坚持第一个选择,这将简单得多。这就是季节性包的作用:从 R 中调用 Census 的X13AS的可执行文件。可执行文件位于x13binary包中。