找到Rcpp中的最小向量

时间:2011-03-01 17:42:08

标签: c++ r rcpp

从昨晚开始,我一直在试用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功能?如果是这样,我在哪里可以找到这样的功能列表?

我猜这个问题与以下内容有关: Where can I learn how to write C code to speed up slow R functions?

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

1 个答案:

答案 0 :(得分:10)

很高兴你发现Rcpp很有用。

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

另外,更常见的方法是使用R中的向量,将其传递给通过内联和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的评论进行了修正。