2

下面是在 R 中创建 3 个应该通过调用 C 代码来操作的矩阵的最小示例

简而言之,我想将矩阵 A 从 R 传递到 C,然后将一些值复制到 W 和 H 矩阵。后 2 我想用修改后的值回到 R 中。

但是,这并不完全有效(段错误或返回的空矩阵)。我怀疑 R 复制对象以在 C 中使用,而不是通过引用传递它们。

C源(test.c):

void test(double *A, double *W, double *H, int m, int n, int k) {
    // A is input with dimensions (m,n)
    // W has dimensions (m,k)
    // H has dimensions (k,n)

    int i;

    for(i=0; i<m*k; i++)
        W[i] = A[i];

    for(i=0; i<k*n; i++)
        H[i] = A[i];
}

一些构建说明(Makefile):

CCFLAGS = -fPIC

all: shared

shared: test.o
    $(CC) -shared -Wl,-soname,test.so -o test.so test.o

test.o: test.c
    $(CC) $(CCFLAGS) -c $<

这就是调用它的 R 代码:

dyn.load("test.so")

m = 3
n = 3
k = 2

A = matrix(c(1:(m*n)), nrow=m, ncol=n)

W = matrix(0, nrow=m, ncol=k)
H = matrix(0, nrow=k, ncol=n)

.C("test", as.double(A), as.double(W), as.double(H), 
   as.integer(m), as.integer(n), as.integer(k))

现在我的问题:

  • 为什么这个段错误大部分时间?
  • 有没有办法用未初始化的 R 矩阵调用 C 函数?
  • 为什么'void'函数会返回一些东西?

而且,最重要的是,

  • 如何让这个工作?
4

1 回答 1

1
  • 为什么这个段错误大部分时间?

这(可能)是因为您的函数采用整数,而.C接口将传入指针。你的签名应该是

void test(double *A, double *W, double *H, int *m, int *n, int *k)
  • 有没有办法用未初始化的 R 矩阵调用 C 函数?

DUP=FALSE在您的调用中设置.C将防止.C复制您传递给它的数组。详情请参阅?.C

  • 为什么'void'函数会返回一些东西?

C 函数不返回任何内容,但 R 函数.C返回一个列表,对应于传递给 C 函数的参数。再次,请参阅?.C

  • 如何让这个工作?

你有两个选择。首先是设置DUP=FALSE并让 C 函数修改现有的 R 对象。但是,如果您这样做,您要确保as.double在将它们传递给外部调用之前调用它们,否则as.double将被迫创建新对象,因为按照当前定义W并且H将是整数类型。

您的第二个选择是离开DUP=TRUE,并使用.C调用的返回值,如下所示:

result<-.C("test", as.double(A), W=as.double(W), H=as.double(H), 
  as.integer(m), as.integer(n), as.integer(k))
W<-result$W
H<-result$H
于 2013-10-25T23:03:49.047 回答