问题描述
我对Fortran完全陌生,并且精通R.我被传授了一个庞大的Fortran程序,其中包含约30个子例程,约15个函数和许多其他代码行.有人告诉我我需要从R调用Fortran程序.我一直在网上搜索方法创建R和Fortran之间的桥梁几乎没有成功.我可以从命令行成功执行Fortran exe文件并创建所需的输出.该fortran文件称为"FortFish.f"
I am totally new to Fortran and well versed with R.I was handed down a huge Fortran program with about 30 subroutines and about 15 functions and many other lines of code.I was told that I needed to call the Fortran program from R. I have been searching online for waysto create this bridge between R and Fortran with very little success.I can successfully execute the Fortran exe file from the command line and create the desired outputs.The fortran file is called "FortFish.f"
一个问题:
从R中,我应该调用Fortran程序还是必须分别调用Fortran函数和子例程?
From R, Do I call the Fortran program or do I have to call Fortran functions and subroutines separately?
在R中,我是否这样调用整个Fortran程序?:R CMD SHLIB FortFish.f,然后使用:dyn.load("FortFish.so")
From R, Do I call the entire Fortran program like this?: R CMD SHLIB FortFish.f and then use:dyn.load("FortFish.so")
如果我无法一次运行整个Fortran程序,我将根据要求发布几个小型的fortran函数和子例程.有没有人使用R和Fortran可以共享的运行示例?
If I cannot run the entire Fortran program at once, I will post a couple of small fortran functions and subroutines upon request.Does anyone have a running example of using R and Fortran that can share?
我的Fortran代码非常大,否则,我将其发布在这里.谢谢.
My Fortran code is extremely large, otherwise, I would post it here.Thank you.
推荐答案
我看到三种可能性:
-
您可以单独编译Fortran程序,并使用R函数
system()
对其进行调用.您将必须通过该程序可以读取的格式通过文件传递数据.
You compile the Fortran program separately, and call it with R function
system()
. You will have to pass data through files, in a format that this program can read.
使用dyn.load()
编译从R加载的DLL,然后使用.Fortran()
调用Fortran函数.您可以轻松地传递数字数据(标量,向量或数组),但是字符串数据更难处理.然后数组被复制.
You compile a DLL that you load from R with dyn.load()
, then you call a Fortran function with .Fortran()
. You can easily pass numeric data (scalars, vectors or arrays), but string data is more difficult to handle. And arrays are copied.
这种调用DLL函数的机制被认为过于简单,现在首选.Call()
,但是要使用.Call()
,则必须编写C包装程序.
This mechanism to call a DLL function is considered too simplistic and now .Call()
is prefered, but to use .Call()
you would have to write C wrappers.
我将举一个第二种可能性的例子.考虑一下Fortran中的一个子例程,该子例程通过Horner算法评估多项式:
I will give an example of the second possibility.Consider a subroutine in Fortran that evaluates a polynomial by Horner's algorithm:
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
从命令行使用以下命令进行编译:
Compile from the command line with:
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上如此):
If you want your Fortran subroutines to print something to RStudio console, you need to do (at least on Windows):
Sys.unsetenv("GFORTRAN_STDOUT_UNIT")
Sys.unsetenv("GFORTRAN_STDERR_UNIT")
这确实是一个简单的例子,一个更复杂的程序将需要更多的工作,但是您明白了.
This is really a trivial example, and a more complex program will require more work, but you get the idea.
如果您的Fortran程序是独立的(它具有一个程序"单元,应该被编译为从命令行调用的可执行文件),并且如果您不熟悉Fortran,那么我建议您坚持使用第一个选择,这会简单得多.这就是打包的季节性所做的事情:调用人口普查 X13AS .可执行文件位于 x13binary 包.
If your Fortran program is standalone (it has a 'program' unit and is supposed to be compiled to an executable called from the command line), and if you are new to Fortran, I would suggest to stick with the first choice, which will be much simpler. That's what the seasonal packaged does: call the executable of Census' X13AS from within R. The executable is in the x13binary package.
这篇关于如何从R调用Fortran程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!