R,.呼叫功能和SEXP结构

12 c r

我正在使用一个非常具体的模拟退火算法为我的问题构建一个包,我对C代码和SEXP有疑问,我无法解决.我不是R的专家,我一直在使用它只有3个星期......但我必须这样做.

据我所知,.CallR中的函数通过引用将参数作为SEXP结构传递给C(即它们不重复).我对吗?如果我在C中使用另一个需要此SEXP结构的第一个函数调用另一个函数怎么办?(见例).我问,因为其中一个参数很大并且使用了很多空间(10 ^ 7~10 ^ 18双倍,虽然我不会在每次迭代中都使用它们)而且我会调用这个函数很多次,所以如果每次我调用它,这个参数都会重复,我会耗尽内存.

MWE:

R电话

MySimAn <- function(def_energy, i_pos, T0, Tfinal){
  ret <- .Call("CMySimAn",def_energy, i_pos, T0, Tfinal, seq0)
  ret
}
Run Code Online (Sandbox Code Playgroud)

C功能

double Energy(SEXP def_energy, SEXP seq0, int i0){
  int i;
  double res=0;
  for(i=0;i<INTEGER(GET_DIM(seq0))[0];i++){
    res += NUMERIC(def_energy)[i0+INTEGER(seq0)[i]];
  }
  return(res);
}

SEXP CmySimAn(SEXP def_energy, SEXP i_pos, SEXP T0, SEXP Tfinal, SEXP seq0){
  SEXP = Ene;
  PROTECT(Ene = NEW_NUMERIC(1));
  REAL(Ene)[0] = Energy(def_energy, seq0, INTEGER(i_pos));
  UNPROTECT(1);
  return Ene;
}
Run Code Online (Sandbox Code Playgroud)

像这样的工作(函数中的代码Energy没有被检查,所以可能是错误的)?每当我调用它时,我是否会创建def_energy的副本,无论是在R还是C?非常感谢您的帮助.

Mar*_*gan 8

代码几乎(语法上)正确写入,并且没有内存复制; 从R传递给C的参数应该被视为"只读".

一个常见的范例是编写一个R/C接口层,在纯(非R)C中从该层调用任何函数.所以

double Energy(const double *def_energy, const int *seq0, int dim0, int i0)
{
  int i;
  double res=0;
  for(i = 0; i < dim0; i++) {
    res += def_energy[i0 + seq0[i]];
  }
  return(res);
}
Run Code Online (Sandbox Code Playgroud)

使用const执行这一来自R传递的值不应该被写入隐性契约.使用R/C包装器

SEXP CmySimAn(SEXP def_energy, SEXP i_pos, SEXP T0, SEXP Tfinal, SEXP seq0){
  double Ene = Energy(REAL(def_energy), INTEGER(seq0), INTEGER(GET_DIM(seq0)[0]),
                      INTEGER(i_pos)[0]);
  return ScalarReal(Ene);
}
Run Code Online (Sandbox Code Playgroud)

数字元素的访问者是REAL()(您NUMERIC在Energy中使用).你的使用PROTECT(...); REAL(Ene)[0] = ...; UNPROTECT(Ene);是正确的.

  • 是的,访问器`INTEGER()`,`REAL()`都是返回点. (3认同)