从R调用Fortran子例程失败

从R调用Fortran子例程失败,r,fortran,call,subroutine,R,Fortran,Call,Subroutine,我试图从R中调用一个简单的Fortran子程序,但出现了一些错误。我成功地编译了Fortran代码(确切地说,我只是这门语言的初学者),但是当我在R中调用子程序时失败了 Fortran代码是一个简单的子例程,它计算(定义的)范围内每个点的函数值。然后将结果存储在大小为2x100000的矩阵(fortran中的数组)中。一行存储函数f(x)的值,另一行存储相应的变量(x) 然后是R打来的电话 y=rnorm(200,0,1) y[1]=4/(1-0.6) for(i in 2:length(y))

我试图从R中调用一个简单的Fortran子程序,但出现了一些错误。我成功地编译了Fortran代码(确切地说,我只是这门语言的初学者),但是当我在R中调用子程序时失败了

Fortran代码是一个简单的子例程,它计算(定义的)范围内每个点的函数值。然后将结果存储在大小为2x100000的矩阵(fortran中的数组)中。一行存储函数f(x)的值,另一行存储相应的变量(x)

然后是R打来的电话

y=rnorm(200,0,1)
y[1]=4/(1-0.6)
for(i in 2:length(y)){
  y[i]=4+0.6*y[i-1]+rnorm(1,0,1)
}

results=matrix(0, nrow=2, ncol=100000)

dyn.load("algo.dll")
    .Fortran('algo',n=as.integer(200), tho=as.integer(100000), c=as.double(4), phi=as.double(0.6), ydata=as.double(y), eps=as.double(0.0001), results=as.double(results) ) 
从R给出的1000次阵列“结果”观察中,绝大多数的数字都是相同的,只有很少的NaN:

$results
   [1]  8.921136e+05  1.000000e-04  8.921136e+05  1.000000e-04  8.921136e+05  1.000000e-04
   [7]  8.921136e+05  1.000000e-04  8.921136e+05  1.000000e-04  8.921136e+05  1.000000e-04
  [13]           NaN           NaN  8.921136e+05  1.000000e-04  8.921136e+05  1.000000e-04
我希望他给我一个[1]f(x1)0.0001f(x2)0.0002的输出

对我来说,问题可能来自3个不同的问题

  • Fortran代码中的错误数学
  • 矩阵/数组的错误使用
  • 来自R(.Fortran(…,n=as…)的子例程调用
但我没能解决它。任何帮助都将不胜感激。谢谢

您可以使用该软件包——这是它的第一个示例:

R> x <- as.numeric(1:10)
R> n <- as.integer(10)
R> code <- "
+       integer i
+       do 1 i=1, n(1)
+     1 x(i) = x(i)**3
+ "
R> cubefn <- cfunction(signature(n="integer", x="numeric"), code, 
+                      convention=".Fortran")
R> print(cubefn)
An object of class 'CFunc'
function (n, x) 
.Primitive(".Fortran")(<pointer: 0x7fc8a8db7660>, n = as.integer(n), 
    x = as.double(x))
<environment: 0x8193e98>
code:
  1: 
  2:        SUBROUTINE file2e6b876b50a29 ( n, x )
  3:       INTEGER n(*)
  4:       DOUBLE PRECISION x(*)
  5: 
  6:       integer i
  7:       do 1 i=1, n(1)
  8:     1 x(i) = x(i)**3
  9: 
 10:       RETURN
 11:       END
 12: 
R> cubefn(n, x)$x
 [1]    1    8   27   64  125  216  343  512  729 1000
R> 
R>xn代码cubefn打印(cubefn)
类“CFunc”的对象
函数(n,x)
.Primitive(“.Fortran”)(,n=as.integer(n),
x=双精度(x))
代码:
1: 
2:子程序文件2E6B876B50A29(n,x)
3:整数n(*)
4:双精度x(*)
5: 
6:整数i
7:Do1i=1,n(1)
8:1 x(i)=x(i)**3
9: 
10:返回
11:完
12: 
R> 立方英尺(n,x)$x
[1]    1    8   27   64  125  216  343  512  729 1000
R>

我会用它来确保你的代码构建和运行,一旦完成,建议创建一个包。

我刚刚编辑了最初的帖子,以提高结果的清晰度。我没有计算机来检查这一点,但在第一个循环中
vecteps(I)=vecteps(I)+eps看起来非常可疑:到目前为止,只定义了
veceps(1)
。也许你的意思是
vecteps=0
(或
vecteps(:)=0
),尽管这两种方法对我以后的循环都没有多大意义?通过这个循环,我尝试生成一个向量,它类似于由R代码创建的向量:“vecteps=seq(from=0.0001,to=10,by=0.0001)”。。。但你是对的,这里似乎失败了。举例说明如何在Fortran中创建/构造这样的数组。
R> x <- as.numeric(1:10)
R> n <- as.integer(10)
R> code <- "
+       integer i
+       do 1 i=1, n(1)
+     1 x(i) = x(i)**3
+ "
R> cubefn <- cfunction(signature(n="integer", x="numeric"), code, 
+                      convention=".Fortran")
R> print(cubefn)
An object of class 'CFunc'
function (n, x) 
.Primitive(".Fortran")(<pointer: 0x7fc8a8db7660>, n = as.integer(n), 
    x = as.double(x))
<environment: 0x8193e98>
code:
  1: 
  2:        SUBROUTINE file2e6b876b50a29 ( n, x )
  3:       INTEGER n(*)
  4:       DOUBLE PRECISION x(*)
  5: 
  6:       integer i
  7:       do 1 i=1, n(1)
  8:     1 x(i) = x(i)**3
  9: 
 10:       RETURN
 11:       END
 12: 
R> cubefn(n, x)$x
 [1]    1    8   27   64  125  216  343  512  729 1000
R>