7

从昨晚开始,我一直在尝试Rcppinline,到目前为止,我真的很享受它。但总的来说,我还是个新手,C只能做基本的事情,而且我很难在网上找到关于功能之类的帮助。

我正在研究的是一个在全局环境中找到向量最小值的函数。我想出了:

library("inline")
library("Rcpp")

foo <- rnorm(100)

bar <- cxxfunction( signature(),
'
Environment e = Environment::global_env();  
NumericVector foo = e["foo"];
int min;

for (int i = 0; i < foo.size(); i++)
{
    if ( foo[i] < foo[min] ) min = i;
}
return wrap(min+1);
', plugin = "Rcpp")

bar()

但似乎应该有一种更简单的方法来做到这一点,而且它比which.max()

system.time(replicate(100000,bar()))
   user  system elapsed 
   0.27    0.00    0.26 
system.time(replicate(100000,which.min(foo)))
   user  system elapsed 
    0.2     0.0     0.2 

我是否忽略了执行此操作的基本功能c++Rcpp功能?如果是这样,我在哪里可以找到此类功能的列表?

我想这个问题与: 我在哪里可以学习如何编写 C 代码来加速慢速 R 函数?

但不同的是,我对如何合并并不真正感兴趣c++R而是更多关于如何以及在何处学习c++可用的基本代码R

4

1 回答 1

10

很高兴您发现 Rcpp 很有用。

比利的第一条评论是非常正确的。函数查找有开销,[]每个元素的查找都有开销等。

此外,更常见的方法是获取 R 中的向量,将其传递给您通过 inline 和 Rcpp 创建的编译函数,并让它返回结果。试试看。包中有大量示例,分布在 rcpp-devel 邮件列表档案中。

编辑:我忍不住尝试建立一个非常 C++/STL 风格的答案。

R> src <- '
+   Rcpp::NumericVector x(xs);
+   Rcpp::NumericVector::iterator it =       // iterator type
+     std::min_element(x.begin(), x.end());  // STL algo
+   return Rcpp::wrap(it - x.begin()); '
R> minfun <- cxxfunction(signature(xs="numeric"), body=src, plugin="Rcpp")
R> minfun(c(7:20, 3:5))
[1] 14
R>

这并不是最简单的答案,但它显示了如何通过使用 C++ 提供的功能,即使在 C++ 级别也可以找到没有(显式)循环的最小元素。但是内置min()函数仍然更快。

*编辑 2:根据以下 Romain 的评论更正。

于 2011-03-01T18:43:04.050 回答