4

我有一些 R 代码,有点慢,所以我一直在尝试使用“内联”库直接在 R 代码中编写一些 C++ 代码。

这很好用,我现在正在尝试调整它。

只有在 R 中分配“结果”数据结构并将它们作为函数参数传递给 c 函数时,我才能使其工作。我想知道是否有可能在 R 代码中有一个非 void c/c++ 函数,这样内存是从 c/c++ 而不是 R 分配和返回的。

请参见下面的示例:

library(inline)
cppSig <- signature(res="numeric",ary="numeric",len="integer")
cppBody <- "
int lens=len[0];
res[0]=0;
  for(int j=0;j<lens;j++)
     res[0] += ary[j];
res[0] /= (double) lens;
#if 0 //Is something like this possible? 
    double *rary = new double[lens];
    for(int i=0;i<lens;i++) rary[i] = ary[i]-res[0];
    return rary;
#endif
"
cfun <- cfunction( sig=list(myMean=cppSig), 
                 body=list(cppBody),verbose=T, 
                 convention=".C", cxxargs="-O3", cppargs="-O3",language="C++")
cfunWrap <- function(x)
  cfun$myMean(res=0,ary=x,length(x))$res


cfunWrap(x=rnorm(100))

谢谢

4

1 回答 1

3

有几件事我会做不同的事情,尤其是在随便看看 Rcpp 文档之后。所以这里只是一个快速列表:

  1. 是的,我们可以使循环更快。经常很多。
  2. 是的,我们可以返回原子 C/C++ 类型以及向量。有很多例子。wrap()这些非向量类型的一种用途;双精度向量会自动返回。但是你永远不会在它们上使用new/ delete。看看Writing R Extensions为什么。
  3. 是的,您可以使用内联包。我们经常使用它。但是我们从不将它.C()cfunction(). 始终使用cxxfunction()或至少启用.Call(). 我不知道你是怎么错过的。
  4. 从 Rcpp 0.10.0 开始,我们有了“Rcpp Attributes”,它比 inline 和它的cxxfunction(). 例如,环顾四周寻找sourceCpp()or cppFunction(),甚至阅读小插图。
  5. 最后,你真的错过了一些基本的东西。您是否阅读了 pdf 小插图 Rcpp-iintroduction 和/或 Rcpp-FAQ?

编辑: 好的,这是一个遵循函数结构的完整示例(但我们可以做得更好,见下文):

#include <Rcpp.h>

using namespace Rcpp; 

// [[Rcpp::export]]
NumericVector monkey(NumericVector ary) {
  int lens = ary.length();   // objects can tell you about their length
  double res=0;
  for(int j=0;j<lens;j++) res += ary[j];
  res /= (double) lens;

  NumericVector rary(lens);
  for(int i=0;i<lens;i++) rary[i] = ary[i]-res;
  return rary;
}

// and we even include some R code to test automagically

/*** R
set.seed(42)
x <- rnorm(5)   # just five to keep printout short
monkey(x)
cat("Check:")
x - mean(x)
*/

如果你调用它,它也会在底部运行 R 代码:

R> Rcpp::sourceCpp('/tmp/monkey.cpp')

R> set.seed(42)

R> x <- rnorm(5)   # just five to keep printout short

R> monkey(x)
[1]  0.9296545 -1.0060021 -0.0781755  0.1915587 -0.0370356

R> cat("Check:")
Check:
R> x - mean(x)
[1]  0.9296545 -1.0060021 -0.0781755  0.1915587 -0.0370356
R>

但是Rcpp 的关键特性之一是您甚至可以在 C++ 中进行向量运算:

R> cppFunction('NumericVector monkey2(NumericVector x) { return x - mean(x); }')
R> monkey2(x)
[1]  0.9296545 -1.0060021 -0.0781755  0.1915587 -0.0370356
R> 

那只是编译了一个新的单行 C++ 函数,该函数对整个向量x进行操作并运行它。

于 2013-06-23T12:33:41.690 回答