R & Fortran 调用

标签 r fortran

我没有使用 Fortran 的经验,但我试图通过 .Fortran() 函数从 R 中调用该语言来运行一个非常简单的循环。每当我运行粘贴在下面的 R 代码的最后一行时,R gui 就会崩溃并且我没有得到任何结果。我有兴趣将实值 x 的向量从 Fortran 带回 R 以进行进一步分析。 g 是 0 到 1 之间的数值,n 是整数,它们都由用户在 R 中提供。

任何帮助将非常感激!最好,

文森特

保存在 bar.f 中的 Fortran 代码:

    subroutine bar(n, g, x)

      integer n
      double precision g
      double precision x(n)
      integer i
      x(1)=1
      do 100 i = 2, n
          x(i) = x(i-1) * g + 1
  100 continue

      end

在 Cygwin 中使用 gfortran 编译 DLL:
gfortran -shared -obar.dll bar.f

代码:
dyn.load("d:/bar.dll")
is.loaded("bar")
.Fortran("bar", n=as.integer(15), g=as.double(5), x=as.double(rnorm(5)))

最佳答案

当我编译你的代码时,我可以执行一次对 .Fortran 的调用。当我第二次运行它时,它崩溃了。但是,我注意到,如果我使为 x 传递的向量与为 n 传递的整数长度相同,则表明它应该是,即:

.Fortran('bar', n = as.integer(15), g = as.double (5), x = as.double(rnorm(15)) )

我可以根据需要多次运行该函数。所以问题可能是你告诉 Fortran 例程它有一个长度为 15 的向量可以使用,但只发送一个长度为 5 的向量。这可能导致 Fortran 例程访问它不应该访问的内存会解释崩溃。

由于看起来您正在例程中生成 x 的所有值,因此您可以跳过生成随机数并使用 R 的 double(n) 函数发送一个空向量,其中 n 是您想要生成的空向量的长度:
.Fortran('bar', n = as.integer(15), g = as.double(5), x = double(15))
integercharacter 是有用的函数,它们返回像 double 这样的向量。

还有一些关于 Fortran 风格的友好建议,因为您提到您刚刚开始使用该语言:
  • 使用 .f90 扩展名来命名您的文件可能是明智的——大多数编译器都假设以 .f 结尾的文件遵循旧的“固定格式”格式,该格式是设计用于 PITA 的卡片.
  • Do 100 ... 100 continue 语句是 Fortran 77 中结束循环的一种风格。现代的等价物是 Do x322513 .18
  • 对于 Fortran 函数和子例程,明智的做法是声明传入和传出例程的变量的“意图”。可用的意图声明是:
  • end do :表示仅作为输入进入例程的变量。一旦进入例程,它们就应该被视为参数,如果尝试更改它们,编译器将引发错误。
  • intent(in) :表示其值应在例程内作为输出生成的变量。如果在例程中未分配意图输出变量,编译器将发出警告。
  • intent(out) :表示可以携带一组特定值进入例程并以不同值离开例程的变量。

  • 在变量上设置意图将帮助编译器生成警告和错误,这可能会为您节省一些错误搜索。
  • Fortran 有一个默认行为,其中任何未在例程头中声明的变量如果名称以 i-n 开头,则为整数,否则为 real。这可能会导致拼写错误的变量名称“神奇地”成为变量,而编译器不会眨眼或告诉您。在例程顶部设置 intent(inout) 会禁用此行为,并允许编译器通知您可能很难追踪的错误。

  • 考虑到这些建议的子程序版本如下所示:
    subroutine bar(n, g, x)
      implicit none
    
      integer, intent(in):: n
      double precision, intent(in):: g
      double precision, intent(inout):: x(n)
    
      integer:: i
    
      x(1) = 1
      do i = 2, n
        x(i) = x(i - 1) * g + 1
      end do
    
    end subroutine bar
    

    此外,让 R 使用 implicit noneSHLIB 子命令编译您的库很有用:
    R CMD SHLIB -o bar.dll bar.f90
    

    这将针对包含有用函数的 R 库编译您的程序——例如 BLAS 例程、统计例程和可以将信息打印到 R 控制台的方法。有关更多信息,请参阅 Writing R Extensions, Section 6

    希望这可以帮助!

    关于R & Fortran 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4731807/

    相关文章:

    r - 在 R 中,函数“print”和 "show"有什么区别?

    r - 保留签名的部分函数

    linux - 链接到模块文件夹提供了未定义的引用

    c++ - 将数组从 C/C++ 传递到 Fortran 并返回计算后的数组

    RMarkdown/pandoc 无法使用 latex 颜色命令编织 Pdf

    r - 改进 R 中数据的曲线拟合

    fortran - 具有重载赋值的嵌套派生类型

    performance - Fortran:32 位/64 位性能可移植性

    r - ggplot2:使用 stat_summary 参数时填充点出现问题

    c - 阅读封闭的命名管道 block