c++ - 如何声明 Rcpp 函数的输入?

标签 c++ r rcpp

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

考虑这个例子:

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

我的理解是这定义了一个函数mat_1在 R 的工作区中,它以一个数字矩阵作为输入,最后返回一个数字矩阵。然而,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 -function 使用对 R 的引用目的。我实际上不确定我是否理解这意味着什么。使用 SEXP 不是重点吗?没有复制,还是我弄错了什么?此外,如果它节省内存并因此更有效率,我为什么还要使用其他东西?

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

  1. 为什么以及何时使用 NumericMatrix 会有所返回而不是 SEXP为了争论,反之亦然?
  2. 为什么以及何时使用 &
  3. 如果我知道该函数将返回一个数字矩阵,是否有理由将该函数声明为 SEXP ?有理由坚持NumericMatrix吗? ?

还是我完全忽略了重点?

此外,mat_2 中使用的转换之间是否存在任何实际差异?和 mat_3 ?也就是说,Rcpp::NumericMatrix x(X) 之间是否存在差异?和 NumericMatrix x(as<NumericMatrix>(X))

欢迎任何反馈。

最佳答案

好的。试图提供一些线索。首先,如果您是初学者,那么您已经正确使用了第一个函数,使用 mat_1 .随着技能的提高,您可能会理解 mat_1 之间的一些差异。和另一个,并最终移动到...使用mat_1 ,因为那是您要使用的那个。

  1. 总是。大多数用户不应使用 SEXP , 曾经。
  2. 在这种情况下没有什么区别。 Rcpp 将知道如何处理引用,但发生的事情几乎是一样的,它会在本地某处创建一个对象并为您提供对它的引用。如果您要调用mat_4,则按值传递和按引用传递之间的区别会有所不同。来自另一个 C++ 函数。
  3. 如果您知道类型,请使用该类型。这就是 Rcpp 的重点。 SEXP是 R 的 catch all 类型,如果你返回 SEXP它可以是任何东西,如果你返回 NumericMatrix你知道通过设计你返回一个数字矩阵,巨大的优势和几乎所有 Rcpp 存在的原因。

我让你决定你是否错过了重点。

一般as<>会更努力地尝试,但在那种情况下并没有什么不同。

简而言之:使用mat_1 .还有很多其他的东西要学,先别管这个。

关于c++ - 如何声明 Rcpp 函数的输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24921887/

相关文章:

c++ - Rcpp:链接到 Shogun C++ 文件时出现问题

c++ - 模板类中的类型转换运算符 - 无论显式如何调用

c++ - 使用 cmake 和 QT 组织多个项目

c++ - 为什么在 C++ 中的静态数组中 &a 和 a 相同?

c++ - 使用 C++ 序列化对象的首选方法

r - 在 R 中自动化成对重要性分组标签的算法

r - 数据框的列名称

r - 桶中的数据分类

c++ - Armadillo :将立方体 subview (管)转换为 vector

构建包中的 Rcpp openmp 插件