2013-01-16 54 views
5

我有一长串继承的FORTRAN77代码,我使用.Fortran()从R调用。 Fortran代码包含一组子程序,当嵌入到Fortran程序中并随后通过命令行进行编译和运行时,Fortran代码就可以工作。但是,当我从R调用它时,它会在第二次调用该函数时使R崩溃。从内部调试Fortran代码R

由于Fortran代码使用很多索引和数组维度作为变量存储,我认为出现了一些问题。在某个时候,Fortran代码正在寻找内存中不应该存在的地方。所以我需要遍历Fortran代码,检查是否所有来自R的代码都是我认为的代码,并且代码完成了我认为它的工作。

如果这是一个R函数,我可以选择使用debug(),添加browser()语句并打印出我希望在代码中看到的任何值。但Fortran代码不允许我使用任何这些东西。如果我理解正确,那么Fortran的屏幕输出将不会被R捕获。

所以,有谁有个想法,我可以如何检查R传递给Fortran代码的参数的类型和值。如果你可以解释如何随后调用从R调用的代码,那将是出色的。

下面是一个例子来说明我的意思。

C An example program 
C 
     PROGRAM EXAMPLE 
     INTEGER N 
     PARAMETER (N=10) 
     REAL X0, X(N),MEAN 

C 
     X0 = 14 
     DO 10 I = 1,10 
     FI = FLOAT(I) 
     X(I) = X0 + FI 
    10 CONTINUE 
     CALL MYSUB(X0,MEAN) 
     END 
C 
C Mysub the subroutine 
C 
     SUBROUTINE MYSUB(X,N,MEAN) 
     INTEGER N 
     REAL X(N), MEAN 
     MEAN = 0 
     DO 20 I = 1,N 
     MEAN = MEAN + X(I) 
    20 CONTINUE 
     MEAN = MEAN/N 
     RETURN 
     END 

说我想调用R的子程序mysub,我想确保我正确地得到X和N.我用下面的函数:

mysub <- function(x){ 
    if(!is.vector(x) | is.numeric(x)) stop("X has to be a numeric vector") 
    n <- length(x) 
    res <- .Fortran('mysub',X=as.single(x), N=as.integer(n), MEAN=single(1)) 
    return(res$MEAN) 
} 
+4

这是一个非常平凡的问题,但为什么不写入文件中输入Fortran子例程的数量而不是屏幕?通过这种方式,您可以检查R和Fortran之间的通信是否正常工作。 –

+0

@BálintAradi现在我觉得很愚蠢...... ;-) Thx。 –

+1

嘿,最好的问题看起来很简单:-) –

回答

4

在您的示例程序调用MYSUB只有2个参数,而不是在MYSUB的定义中发现的3:(X,N,MEAN)

这可能有无关你的问题,但是因为你在调试FORTRAN和争论,所以我想我应该指出。 FORTRAN子程序是独立的编译。没有什么可以阻止你传递不正确数量的参数(没有编译器错误或链接提示),这可能会导致问题。