我没有使用Fortran的经验,但是我试图通过使用.Fortran()函数从R调用它来运行该语言中的一个非常简单的循环.每当我运行下面粘贴的R代码的最后一行时,R gui崩溃,我得不到任何结果.我有兴趣将Fortran的实数x向量带回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
Run Code Online (Sandbox Code Playgroud)
使用gfortran在Cygwin中编译DLL:
gfortran -shared -obar.dll bar.f
Run Code Online (Sandbox Code Playgroud)
R代码:
dyn.load("d:/bar.dll")
is.loaded("bar")
.Fortran("bar", n=as.integer(15), g=as.double(5), x=as.double(rnorm(5)))
Run Code Online (Sandbox Code Playgroud)
Sha*_*pie 26
当我编译你的代码时,我可以执行.Fortran一次调用.当我第二次运行时,它会崩溃.但是,我注意到如果我传递的矢量x长度与传递的整数相同,则n表明它应该是,即:
.Fortran('bar', n = as.integer(15), g = as.double (5), x = as.double(rnorm(15)) )
Run Code Online (Sandbox Code Playgroud)
我可以根据需要多次运行该功能.所以问题可能是你告诉Fortran例程它有一个长度为15的向量,但只发送一个长度为5的向量.这可能导致Fortran例程访问它本不应该的内存会解释一下崩溃.
因为看起来你正在生成x例程中的所有值,所以你可以跳过生成随机数,然后使用R double(n)函数发送一个空向量,其中n是你想要生成的空向量的长度:
.Fortran('bar', n = as.integer(15), g = as.double(5), x = double(15))
Run Code Online (Sandbox Code Playgroud)
integer并且character是返回向量之类的有用函数double.
关于Fortran风格的一些友好建议,因为你提到你只是开始使用该语言:
用.f90扩展名命名文件可能是明智的--- .f大多数编译器都假定文件结尾,以遵循旧的"固定格式"格式,这是一种PITA,因为它设计用于打卡.
该Do 100... 100 continue语句是Fortran 77中结束循环的风格相当于现代的是Do... end do.
使用Fortran函数和子例程,声明传入和传出例程的变量的"意图"是明智的.可用的意图声明是:
intent(in):表示仅作为输入进入例程的变量.进入例程后,应将它们视为参数,如果尝试更改它们,编译器将引发错误.
intent(out):表示应在例程内生成值作为输出的变量.如果未在例程中分配intent out变量,编译器将发出警告.
intent(inout):表示可能进入带有一组特定值的例程的变量,并使例程保持不同的值.
在变量上设置意图将有助于编译器生成警告和错误,这可能会为您节省一些错误.
Fortran有一个默认行为,其中任何未在例程头中声明的变量如果名称以in开头则为整数,否则为real.这可能会导致拼写错误的变量名称"神奇地"成为变量而无需编译器瞄准或告诉您.设置implicit none在例程的顶部会禁用此行为,并允许编译器通知您可能非常难以跟踪的错误.
将这些建议考虑在内的子程序版本如下所示:
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
Run Code Online (Sandbox Code Playgroud)
另外,让R使用以下SHLIB子命令编译库是很有用的R CMD:
R CMD SHLIB -o bar.dll bar.f90
Run Code Online (Sandbox Code Playgroud)
这将针对包含有用函数的R库编译程序,例如BLAS例程,统计例程和可以将信息打印到R控制台的方法.有关详细信息,请参阅编写R扩展,第6节.
希望这可以帮助!