Fortran是最古老的计算机语言之一,是专为数值计算设计的,在过去几十年中积累了大量代码。很多情况下,人们无需用R或Python重新实现fortran中已有的算法, 而是直接调用这些Fortran代码即可。相对其他编程语言,Fortran比较简单,而且很多编译器经过多次优化,代码的执行效率非常高,一般会超过C语言。虽然Fortran已经60岁了,但在涉及高性能计算的很多领域,如天文、物理、气象、统计等学科中仍发挥着重要作用。
Fortran语言的标准包括F77,F90,F95,F2003, F2008等。每一次版本调整, 一般是为语言增加部分新的特性。最常用的Fortran版本为F77和F90。Fortran77版本编写的代码,扩展名为.f, 以固定格式书写;而Fortran90的源代码文件,扩展名一般为f90,以相对自由的格式书写。
本文简要介绍在R中如何调用Fortran77和Fortran90代码,最后介绍在inline程序包中编译和调用fortran代码。
在R中调用Fortran代码的基本流程是:先将Fortran用gfortran编译为shared library。 在Windows下,要将fortran源代码编译为动态链接库 dll, 在Linux和Mac下编译为so文件。编译过程可通过cmd或者terminal调用gfortran(或者其他fortran编译器)实现,也可以直接在R中用system()函数调用gfortran编译。
在R中,用dyn.load()函数加载编译好的bishared library。
在R中,使用.Fortran()函数调用shared library中的代码,结果将以List的格式返回。
目标:
计算n的阶乘n!=∏nk=1k∀n≥1源代码用Fortran写成。
所需软件
方法1,编译代码后加载和调用Fortran代码
将Fortran代码编译为share library后,再用R的.Fortran函数调用。
编译和调用Fortran77代码
Fortran 77源代码C Content of file factorial.f
C FINDING THE FACTORIAL IN FORTRAN 77
SUBROUTINE FACTO1(N,ANSWER)
INTEGER N, ANSWER, I
ANSWER = 1
DO 100 I = 2,N
ANSWER = ANSWER * I
100 CONTINUE
END
Mac和Linux下的R脚本setwd("/Users/jinlong/Desktop/fortran_example/fortran77/")
system("R CMD SHLIB factorial.f")
dyn.load("factorial.so")
.Fortran("facto1",n=as.integer(5),answer=as.integer(1))
Windows下的R脚本setwd("C:\Users\jlzhang\Desktop\fortran77")
system("Rcmd SHLIB factorial.f")
dyn.load("factorial.dll")
.Fortran("facto1",n=as.integer(5),answer=as.integer(1))
编译和调用Fortran90代码
Fortran90源代码! Content of file factorial.f90
! Finding the factorial in Fortran 90
subroutine facto2(n,answer)
implicit none
integer n, answer, i
answer = 1
do i = 2,n
answer = answer * i
end do
end subroutine facto2
Linux下的R代码setwd("/Users/jinlong/Desktop/fortran_example/fortran90/")
system("R CMD SHLIB factorial.f90")
dyn.load("factorial.so")
.Fortran("facto2",n=as.integer(5),answer=as.integer(1))
Windows下的R代码setwd("C:\Users\jlzhang\Desktop\fortran90")
system("Rcmd SHLIB factorial.f90")
dyn.load("factorial.dll")
.Fortran("facto2", n=as.integer(5), answer=as.integer(1))
方法2,使用inline程序包library(inline)
fcode
integer::i
do i = 2, n(1)
res(1) = res(1) * i
end do
"
fcodefun
fcode, convention=".Fortran")
fcodefun(n = as.integer(5), res = as.integer(1))
若要将Fortran编写到程序包中, 则需要将fortran源代码放入src文件夹中, 用.Fortran()直接调用fortran中的subroutine。R程序包的源代码中是不允许有已经编译好的可执行程序的, 因为这会造成安全风险以及可移植性的问题。注意,.Fortran()中的参数数据类型,必须与fortran代码中的类型一致,一般用 as.integer, as.double, as.character等转换成fortran代码能识别的数据类型。
参考资料
转载本文请联系原作者获取授权,同时请注明本文来自张金龙科学网博客。
链接地址:http://blog.sciencenet.cn/blog-255662-886943.html
上一篇:山寨版 Color Checker
下一篇:用git在github上托管代码