我有以下问题。我有一个文件,比如说file.f90,其中我实现了一些Fortran子例程,比如说foo。然后我使用“R CMD SHLIB file.f90”编译这些函数。为了在一个单独的R文件中使用函数foo,我使用dyn.load(“foo.dll”)并将其命名为.Fortran(“foo”,...)。
到目前为止一切顺利。但是现在我需要使用一些在Lapack中实现的函数。
我不知道该怎么做,也不知道该去哪里看看。我只试过调用“R CMD SHLIB file.f90 -llapack”,但已经出现了一个错误,说没有找到llapack。任何提示都将不胜感激!!
编辑:在在座各位的帮助下,我终于找到了问题的答案。我不得不说,这个解决方案相当简单,但由于我是一个新手,所以在这些方面还是花了一些时间。下面是我针对Windows 11和R Studio 4.1的解决方案
假设我们的R会话/项目具有路径PATH_PROJ,例如“C:\Users\Myname\Documents\MyProject”。然后我创建了一个名为“f90 files”的新文件夹,我打算在其中保存所有Fortran函数,因此PATH_PROJ\f90files。接下来,我需要我的R的Lapack PATH_LAPACK的路径,例如“C:\Program Files\R\R-4.1.2\bin\x64\Rlapack.dll”。
在PATH_PROJ\f90文件中,我按照Jean-Claude Arbaut的建议实现了Fortran子例程:
subroutine eigvals(n, a, vre, vim, info)
implicit none
integer :: n, info
integer, parameter :: lwork = 65536
double precision :: a(n, n), vre(n), vim(n)
double precision, save :: work(lwork)
call dgeev("n", "n", n, a, n, vre, vim, 0d0, 1, 0d0, 1, work, lwork, info)
end subroutine
接下来,我启动了Windows命令提示符并键入
gfortran -shared PATH_LAPACK PATH_PROJ\f90files\eigvals.f90 -o PATH_PROJ\f90files\eigvals.so -o PATH_PROJ\f90files\eigvals.dll
并且还
gfortran -shared PATH_LAPACK PATH_PROJ\f90files\eigvals.f90 -o PATH_PROJ\f90files\eigvals.so
(也许这可以一次完成?)
有了这个,所有的都被很好地编译了。在R中,我使用
dyn.load("PATH_PROJ\f90files\eigvals.dll")
最后,使用下面给出的实现,我运行了
eigvals <- function(a) {
if (is.matrix(a) && is.double(a) && nrow(a) == ncol(a)) {
n <- nrow(a)
s <- .Fortran("eigvals", n = as.integer(n), a = a, vre = double(n), vim = double(n), info = 0L)
structure(complex(real = s$vre, imaginary = s$vim), info = s$info)
} else stop("Invalid input")
}
eigvals(a)
瞧,我们完成了!再次感谢大家!
1条答案
按热度按时间byqmnocz1#
您要查找的库是R-4.2.2\bin\x64目录中的Rblas.dll和Rlapack.dll(用您的版本替换4.2.2)。
这里有一个例子,让我们用LAPACK的
dgeev
来计算特征值。Fortran文件
eigvals.f90
。这里为了简化,lwork
是一个常量,但是在“真实的”代码中,你必须更小心地这样做。使用以下命令之一编译(根据需要更改路径)。如果您在Windows上,请从Rtools bash窗口执行此操作。在Linux上,扩展名是.so而不是. dll。
在R中,现在可以这样做,假设您将
setwd()
指向包含DLL的目录:注意
.Fortran
中子例程参数的数量和类型,否则可能会使R崩溃。还要注意,必须调用Fortran子例程,而不是函数。如果您在Windows上使用R-4.2和Rtools 4.2,还有一个额外的技巧:编译器不再位于默认目录中。请参见this。首先,您必须在Rtools bash窗口中执行以下操作:
如果从Windows命令提示符使用编译器,则必须相应地修改PATH环境变量。