从R调用Fortran子例程失败
我试图从R中调用一个简单的Fortran子程序,但出现了一些错误。我成功地编译了Fortran代码(确切地说,我只是这门语言的初学者),但是当我在R中调用子程序时失败了 Fortran代码是一个简单的子例程,它计算(定义的)范围内每个点的函数值。然后将结果存储在大小为2x100000的矩阵(fortran中的数组)中。一行存储函数f(x)的值,另一行存储相应的变量(x) 然后是R打来的电话从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))
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>