如何将输入声明为Rcpp函数?

时间:2014-07-23 22:09:18

标签: c++ r rcpp

我是一个绝对的Rcpp - 初学者,所以请注意,初学者的问题即将来临。

考虑这个例子:

#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix mat_1(NumericMatrix X){
 do.stuff.with.X
}

我的理解是,它在R的工作空间中定义了一个函数mat_1,它将一个数字矩阵作为输入,并在最后返回一个数字矩阵。但是,looking e.g. here我明白我也可以定义

SEXP mat_2(SEXP X){
Rcpp::NumericMatrix x(X);                 
 do.stuff.with.x
}

或者

SEXP mat_3(SEXP X){
NumericMatrix x(as<NumericMatrix>(X))
 do.stuff.with.x
}

我的理解是,它将函数的输出定义为S表达式,它需要一个S表达式作为输入,它在内部转换(?)为数字矩阵。

现在,looking at this document,这对我来说是一个非常宝贵的资源,我知道我也可以写

NumericMatrix mat_4( NumericMatrix X&){
 do.stuff.with.X
}

在此,我的理解是,X - 函数不是复制Rcpp,而是使用对R对象的引用。我其实不确定我明白这意味着什么。使用SEXP是不是没有复制,或者我弄错了?此外,如果它节省了内存并因此更有效,为什么我会使用其他东西?

我确信我错过了一些选择。无论如何,我的大问题是:R用户(我)的角度来看,我调用每个函数mat_1, mat_2, mat_3mat_4提供数字矩阵(在我的工作区中是一个R对象,因此是SEXP),似乎我应该得到相同的输出(一个数字矩阵,无论如何都是SEXP {{1}透视,对吗?)。对于这些看似相同的定义函数的方法的相对优点,我将不胜感激。也就是说,假设我们确切地知道函数输入将是什么以及输出将是什么,

  1. 为什么以及何时使用R代替NumericMatrix作为参数获得回报,反之亦然?
  2. 为什么以及何时使用SEXP
  3. 如果我知道该函数将返回一个数字矩阵,是否有理由将该函数声明为&?是否有理由坚持SEXP
  4. 还是我完全忽略了这一点?

    此外,NumericMatrixmat_2中使用的转换之间是否有任何实际差异?也就是说,mat_3Rcpp::NumericMatrix x(X)之间是否存在差异?

    感谢任何反馈。

1 个答案:

答案 0 :(得分:5)

好的。试图给出一些线索。首先,如果您是初学者,使用第一个函数就可以正确使用mat_1。随着您的技能提升,您可能会理解mat_1与另一个之间的一些差异,并最终转向...使用mat_1,因为这是您要使用的那个。

  1. 始终。大多数用户不应该使用SEXP
  2. 在这种情况下没有任何区别。 Rcpp将知道如何处理引用,但发生的情况几乎相同,它会在某处创建一个对象,并为您提供引用。如果你要从另一个C ++函数调用mat_4,那么传递值和引用之间的区别会有所不同。
  3. 如果您知道类型,请使用类型。这是Rcpp的全部观点。 SEXP是R的所有类型,如果你返回一个SEXP它可以是任何东西,如果你返回一个NumericMatrix,你知道你在设计中返回一个数字矩阵,巨大的优势和Rcpp存在的全部原因。
  4. 我让你决定你是否错过了这一点。

    一般来说as<>会更加努力,但在这种情况下并没有什么不同。

    简而言之:使用mat_1。还有很多其他的东西要学习,不要关心这个。