r - 如何从 R 调用 Fortran 程序

标签 r fortran interop

我对 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 代码非常大,否则,我会把它贴在这里。
谢谢你。

最佳答案

我看到了三种可能性:

  • 您单独编译 Fortran 程序,并使用 R 函数调用它 system() .您必须以该程序可以读取的格式通过文件传递数据。
  • 您使用 dyn.load() 编译从 R 加载的 DLL ,然后您使用 .Fortran() 调用 Fortran 函数.您可以轻松传递数字数据(标量、向量或数组),但字符串数据更难处理。并复制数组。
  • 这种调用 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
    
    从命令行编译:
    R CMD SHLIB horner.f90
    
    从 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)
    
    如果您希望 Fortran 子程序将某些内容打印到 RStudio 控制台,则需要执行以下操作(至少在 Windows 上):
    Sys.unsetenv("GFORTRAN_STDOUT_UNIT")
    Sys.unsetenv("GFORTRAN_STDERR_UNIT")
    
    这确实是一个微不足道的例子,一个更复杂的程序需要更多的工作,但你明白了。

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

    关于r - 如何从 R 调用 Fortran 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63459875/

    相关文章:

    fortran - 如何从函数访问父变量

    c# - 从 C# 访问 COM vtable

    r - Shiny 的服务器-如何使用session $ onSessionEnded()

    r - 消除垂直线ggplot

    c++ - 从 fortran 写出二进制文件并用 C 读取

    linux - Fortran:如何获取集群的节点名称

    excel - 如何让Excel忽略单元格开头的撇号

    c# - 我可以控制分配给互操作程序集的版本号吗?

    r - 基于ggplot r中数字大小的刻度标签中小数的条件格式

    performance - 为什么加载缓存的对象会大大增加内存消耗而计算它们不会?